poj 1201 Intervals 差分約束系統
阿新 • • 發佈:2020-09-19
Poj 1201 Intervals
題目連結
差分約束系統。
設\(s[x]\)表示從橫座標為0到橫座標為\(x\)的最少點數,所以求出\(s[maxn]\)就好了。(\(maxn\)為橫座標最大的數)
根據每個區間最少的點數,我們可以得到:\(s[y] - s[x - 1] >= c\);
另外還要是後面的大於等於前面的:\(s[i] - s[i - 1] >= 0\);
因為相鄰的最多隻差一,所以:\(s[i] - s[i - 1] <= 1\)。
還有:dij一定不能用在帶有負邊權的圖中!!!這道題只能用SPFA。(我傻不愣登的調了一上午dij)
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #define int long long using namespace std; inline long long read() { long long s = 0, f = 1; char ch; while(!isdigit(ch = getchar())) (ch == '-') && (f = -f); for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48)); return s * f; } const int N = 5e5 + 5, inf = 1e9; int n, maxn, minn, cnt; int in[N], vis[N], dis[N], head[N]; struct edge { int to, nxt, val; } e[N << 2]; void add(int x, int y, int z) { e[++cnt].nxt = head[x]; head[x] = cnt; e[cnt].to = y; e[cnt].val = z; } void run_dij() { memset(dis, 128, sizeof(dis)); queue <int> q; q.push(minn); dis[minn] = 0; while(!q.empty()) { int x = q.front(); q.pop(); in[x] = 0; for(int i = head[x]; i ; i = e[i].nxt) { int y = e[i].to; if(dis[y] < dis[x] + e[i].val) { dis[y] = dis[x] + e[i].val; if(!in[y]) in[y] = 1, q.push(y); } } } } signed main() { n = read(); maxn = -inf; minn = inf; for(int i = 1, x, y, z;i <= n; i++) { x = read() + 1, y = read() + 1, z = read(), add(x - 1, y, z); maxn = max(maxn, max(x - 1, y)); minn = min(minn, min(x - 1, y)); } for(int i = minn;i <= maxn; i++) { if(i != minn) add(i - 1, i, 0), add(i, i - 1, -1); } run_dij(); printf("%lld", dis[maxn]); return 0; }