题干:
背景
小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 样例解释 三个农场种植的数量可以为(2,2,1)
题目大意:
中文题意。
解题报告:
就是个差分约束的板子题,建完图之后就看有没有负环就可以。但是这题不保证点是连通的,所以你如果要直接跑负环的话需要以每一个点为起点开始跑,显然是不合算的,所以最好的方式就是新建一个点,让他到每一个点的连一条权值为0的边,这样就联系起来了。
理性的解释一下也解释得通,因为你要加上一个点使得对原约束没有任何影响(即不放大原有条件也不缩小原有条件(也就是添加新的约束)),就相当于0号点的值本该是-INF,所以加上了:对任意一个点V,,这样一个限制,X0的取值是-INF,保证合法。
当然为了合法你加边的时候权值是INF也行(当然得用longlong了不然就溢出了),代表的含义是
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
const int INF = 0x3f3f3f3f;
struct Edge {int ne,v,w;
} e[MAX];
int tot,n,m;
int head[MAX];
void add(int u,int v,int w) {e[++tot].v = v;e[tot].w = w;e[tot].ne = head[u];head[u] = tot;
}
int dis[MAX],cnt[MAX],vis[MAX];
bool spfa(int st) {memset(dis,INF,sizeof dis);queue<int> q;dis[st]=0;q.push(st);vis[st]=1;
// cnt[st]=1;while(q.size()) {int cur = q.front(); q.pop();vis[cur]=0;for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(dis[v] <= dis[cur] + e[i].w) continue;dis[v] = dis[cur] + e[i].w;if(!vis[v]) {cnt[v]=cnt[v]+1;vis[v]=1;q.push(v);if(cnt[v] > n) return 0;}}}return 1;
}
int main()
{memset(head,-1,sizeof head);cin>>n>>m;for(int op,a,b,c,i = 1; i<=m; i++) {scanf("%d%d%d",&op,&a,&b);if(op != 3) scanf("%d",&c);if(op == 1) add(a,b,-c);if(op == 2) add(b,a,c);if(op == 3) {add(a,b,0);add(b,a,0);}}for(int i = 1; i<=n; i++) add(0,i,0);if(spfa(0)) puts("Yes");else puts("No");return 0 ;
}