BZOJ 3436: 小K的农场( 差分约束 )

orz云神...

真的给跪了...BFS版spfa T 掉了...然后DFS版的就A了...我现在很迷茫....

这就是个普通的差分约束... 

------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<iostream>
 
#define rep(i, n) for(int i = 0; i < n; ++i)
#define clr(x, c) memset(x, c, sizeof(x))
 
using namespace std;
 
const int maxn = 10010;
 
struct edge {
int to, w;
edge*next;
} E[maxn << 1], *pt = E, *head[maxn];
 
inline void add_edge(int u, int v, int d) {
pt->to = v, pt->w = d;
pt->next = head[u];
head[u] = pt++;
}
 
int d[maxn], inS[maxn], cnt[maxn], n;
stack<int> S;
 
bool spfa() {
rep(i, n)
S.push(i), inS[i] = true, cnt[i] = 1, d[i] = 0;
while(!S.empty()) {
int x = S.top(); S.pop();
inS[x] = false;
for(edge*e = head[x]; e; e = e->next) if(d[e->to] > d[x] + e->w) {
   d[e->to] = d[x] + e->w;
   if(!inS[e->to]) {
    if(++cnt[e->to] > n) return false;
       S.push(e->to), inS[e->to] = true;
   }
}
}
return true;
}    
 
inline int read() {
char c = getchar();
for(; !isdigit(c); c = getchar());
int ans = 0;
for(; isdigit(c); c = getchar())
   ans = ans * 10 + c - '0';
return ans;
}
 
void init() {
clr(head, 0);
n = read();
int m = read();
while(m--) {
int t = read(), u = read() - 1, v = read() - 1;
if(t == 3) 
   add_edge(u, v, 0), add_edge(v, u, 0);
else {
int w = read();
t == 1 ? add_edge(u, v, -w) : add_edge(v, u, w);
}
}
}
 
int main(){
freopen("test.in", "r", stdin);
init();
printf(spfa() ? "Yes " : "No ");
return 0;

  

------------------------------------------------------------------------------ 

3436: 小K的农场

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 351  Solved: 186
[Submit][Status][Discuss]

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一样多输出格式

Output

    如果存在某种情况与小K的记忆吻合,输出”Yes”,否则输出”No”

Sample Input

33
312
1131
2232

Sample Output


Yes

样例解释

三个农场种植的数量可以为(2,2,1)。


对于100%的数据,1<=n,m,a,b,c<=10000


HINT

Source

原文地址:https://www.cnblogs.com/JSZX11556/p/4657366.html