BZOJ 3436 小K的农场 差分约束
Description
背景
小K是个特么喜欢玩MC的孩纸。。。
描述
小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得
一些含糊的信息(共m个),以下列三种形式描述:农场a比农场b至少多种植了c个单位的作物,农场a比农场b至多
多种植了c个单位的作物,农场a与农场b种植的作物数一样多。但是,由于小K的记忆有些偏差,所以他想要知道存
不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。
Input
第一行包括两个整数n和m,分别表示农场数目和小K记忆中的信息的数目接下来m行:如果每行的第一个数是1,接
下来有三个整数a,b,c,表示农场a比农场b至少多种植了c个单位的作物如果每行第一个数是2,接下来有三个整数a
,b,c,表示农场a比农场b至多多种植了c个单位的作物如果每行第一个数是3,接下来有两个整数a,b,表示农场a
种植的数量与b一样。1<=n,m,a,b,c<=10000
Output
如果存在某种情况与小K的记忆吻合,输出”Yes”,否则输出”No”
Sample Input
3 3
3 1 2
1 1 3 1
2 2 3 2
3 1 2
1 1 3 1
2 2 3 2
Sample Output
Yes
差分约束有一段时间没做了,又看了一遍,感觉比以前有了更好的认识。
接下来是证明:
然后,相等的情况,只需要连一条边,不然的话,相当于一个 0 的长度的环,又不能松弛,也不会死循环在里面,但是,在遍历邻接表的时候;
每次都做了无用的比较。
1 /************************************************************** 2 Problem: 3436 3 User: TreeDream 4 Language: C++ 5 Result: Accepted 6 Time:140 ms 7 Memory:2220 kb 8 ****************************************************************/ 9 10 #include <bits/stdc++.h> 11 12 using namespace std; 13 14 const int maxn = 10010; 15 16 struct Edge 17 { 18 int from,to,dist; 19 }; 20 21 inline int getint() 22 { 23 int w=0,q=0; char c=getchar(); 24 while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 25 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w; 26 } 27 28 struct BellmanFord 29 { 30 int n,m; 31 vector<Edge> edges; 32 vector<int> G[maxn]; 33 bool inq[maxn]; 34 int d[maxn]; 35 int p[maxn]; 36 int cnt[maxn]; 37 38 void init(int n) 39 { 40 this->n = n; 41 for(int i=0; i<n; i++) G[i].clear(); 42 edges.clear(); 43 } 44 45 void AddEdge(int from,int to,int dist) 46 { 47 edges.push_back((Edge) 48 { 49 from,to,dist 50 }); 51 m = edges.size(); 52 G[from].push_back(m-1); 53 } 54 55 bool negativeCycle() 56 { 57 queue<int> Q; 58 memset(inq,0,sizeof(inq)); 59 memset(cnt,0,sizeof(cnt)); 60 for(int i=0; i<n; i++) 61 { 62 d[i] = 0; 63 inq[0] = true; 64 Q.push(i); 65 } 66 67 while(!Q.empty()) 68 { 69 int u = Q.front(); 70 Q.pop(); 71 inq[u] = false; 72 for(int i=0; i<G[u].size(); i++) 73 { 74 Edge& e = edges[G[u][i]]; 75 if(d[e.to]>d[u]+e.dist) 76 { 77 d[e.to] = d[u] + e.dist; 78 p[e.to] = G[u][i]; 79 if(!inq[e.to]) { 80 Q.push(e.to); 81 inq[e.to] = true; 82 if(++cnt[e.to]>n) 83 return true; 84 } 85 } 86 } 87 } 88 return false; 89 } 90 91 }; 92 93 BellmanFord sol; 94 95 int main() 96 { 97 int n,m; 98 n = getint(); 99 m = getint(); 100 101 sol.init(n+1); 102 int a,b,c; 103 int flag; 104 while(m--) 105 { 106 flag = getint(); 107 //scanf("%d",&flag); 108 if(flag==2) 109 { 110 a = getint(); 111 b = getint(); 112 c = getint(); 113 //scanf("%d%d%d",&a,&b,&c); 114 sol.AddEdge(b,a,c); 115 } 116 else if(flag==1) 117 { 118 a = getint(); 119 b = getint(); 120 c = getint(); 121 //scanf("%d%d%d",&a,&b,&c); 122 sol.AddEdge(a,b,-c); 123 } 124 else if(flag==3) 125 { 126 a = getint(); 127 b = getint(); 128 //scanf("%d%d",&a,&b); 129 sol.AddEdge(a,b,0); 130 //sol.AddEdge(b,a,0); 131 } 132 } 133 for(int i=0; i<n; i++) 134 sol.AddEdge(0,i,0); 135 136 if(sol.negativeCycle()) 137 { 138 puts("No"); 139 } 140 else puts("Yes"); 141 142 return 0; 143 }