//目录

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

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 }
View Code

 

 
 
posted @ 2017-03-18 23:41  小草的大树梦  阅读(258)  评论(0编辑  收藏  举报