差分约束系统
我们把前缀和看成一个点,每个点之间的关系就是sum[i]-sum[j-1]=?,然后我们拆成sum[i]-sum[j-1]>=?和sum[j-1]-sum[i]>=-?,大于等于号是跑最长路,边从b连向a,边权是符号后面的常数项,然后跑最长路就行了,我们可以用dfs版spfa跑
#include<bits/stdc++.h> using namespace std; const int N = 2010; struct edge { int nxt, to, w; } e[N << 1]; int n, m, cnt = 1; int head[N], d[N], vis[N], in[N]; void link(int u, int v, int w) { e[++cnt].nxt = head[u]; head[u] = cnt; e[cnt].to = v; e[cnt].w = w; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); memset(head, 0, sizeof(head)); cnt = 1; for(int i = 1; i <= m; ++i) { int l, r, v; scanf("%d%d%d", &l, &r, &v); link(l - 1, r, v); link(r, l - 1, -v); } queue<int> q; for(int i = 0; i <= n; ++i) q.push(i), in[i] = d[i] = 0, vis[i] = 1; bool flag = true; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; i; i = e[i].nxt) if(d[e[i].to] < d[u] + e[i].w) { d[e[i].to] = d[u] + e[i].w; if(vis[e[i].to] == 0) { ++in[e[i].to]; if(in[e[i].to] == n) { puts("false"); flag = false; break; } vis[e[i].to] = 1; q.push(e[i].to); } } if(!flag) break; } if(flag) puts("true"); } return 0; }
时间: 2024-11-06 19:37:28