POJ 2983 Is the Information Reliable?(差分约束)
题意:两种信息 ,p是代表确定信息sv在ev的北边多w,v是代表sv在ev北边至少1不确定。
差分约束,还是不太懂啊,自己想了个扯淡的算法,非常复杂而且还不对。。。
看了看题解做法,这个题目做法是化等式为不等式,然后构造超级源点,判断是否有负环存在。
sv - ev = w 化为 sv - ev >= w &&sv - ev <= w
然后建图,一遍spfa就行了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <queue> 6 #include <cstdlib> 7 #include <ctime> 8 #include <map> 9 using namespace std; 10 #define INF 10000000 11 struct node 12 { 13 int u,v,next,w; 14 } edge[1000100]; 15 int first[3001],d[3001]; 16 int n; 17 int t; 18 void CL() 19 { 20 t = 1; 21 int i; 22 for(i = 1; i <= n; i ++) 23 first[i] = -1; 24 for(i = 1;i <= n;i ++) 25 d[i] = 0; 26 } 27 void add(int u,int v,int w) 28 { 29 edge[t].u = u; 30 edge[t].v = v; 31 edge[t].w = w; 32 edge[t].next = first[u]; 33 first[u] = t; 34 t ++; 35 } 36 int main() 37 { 38 int i,m,j,u,v,flag,sv,ev,w; 39 char ch; 40 while(scanf("%d%d%*c",&n,&m)!=EOF) 41 { 42 CL(); 43 for(i = 1; i <= m; i ++) 44 { 45 scanf("%c",&ch); 46 if(ch == 'V') 47 { 48 scanf("%d%d%*c",&sv,&ev); 49 add(ev,sv,1); 50 } 51 else 52 { 53 scanf("%d%d%d%*c",&sv,&ev,&w); 54 add(ev,sv,w); 55 add(sv,ev,-w); 56 } 57 } 58 for(i = 1; i <= n+1; i ++) 59 { 60 flag = 0; 61 for(j = 1;j < t;j ++) 62 { 63 u = edge[j].u; 64 v = edge[j].v; 65 if(d[v] < d[u] + edge[j].w) 66 { 67 d[v] = d[u] + edge[j].w; 68 flag = 1; 69 } 70 } 71 if(!flag) 72 break; 73 } 74 if(!flag) 75 printf("Reliable\n"); 76 else 77 printf("Unreliable\n"); 78 } 79 return 0; 80 }