差分约束系统。。找负环用spfa就行
——代码
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define N 100001 5 6 int n, m, cnt; 7 int head[N], to[N << 1], val[N << 1], next[N << 1], dis[N]; 8 bool vis[N]; 9 10 inline int read() 11 { 12 int x = 0, f = 1; 13 char ch = getchar(); 14 for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; 15 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; 16 return x * f; 17 } 18 19 inline void add(int x, int y, int z) 20 { 21 to[cnt] = y; 22 val[cnt] = z; 23 next[cnt] = head[x]; 24 head[x] = cnt++; 25 } 26 27 inline bool spfa(int u) 28 { 29 int i, v; 30 vis[u] = 1; 31 for(i = head[u]; i ^ -1; i = next[i]) 32 { 33 v = to[i]; 34 if(dis[v] > dis[u] + val[i]) 35 { 36 dis[v] = dis[u] + val[i]; 37 if(vis[v]) return 0; 38 else if(!spfa(v)) return 0; 39 } 40 } 41 vis[u] = 0; 42 return 1; 43 } 44 45 int main() 46 { 47 int i, j, opt, x, y, z; 48 n = read(); 49 m = read(); 50 memset(head, -1, sizeof(head)); 51 for(i = 1; i <= m; i++) 52 { 53 opt = read(); 54 x = read(); 55 y = read(); 56 if(opt == 3) add(x, y, 0), add(y, x, 0); 57 else 58 { 59 z = read(); 60 if(opt == 1) add(x, y, -z); 61 if(opt == 2) add(y, x, z); 62 } 63 } 64 memset(dis, 127 / 3, sizeof(dis)); 65 for(i = 1; i <= n; i++) add(0, i, 0); 66 dis[0] = 0; 67 spfa(0) ? puts("Yes") : puts("No"); 68 return 0; 69 }