这个题是一道差分约束系统的裸题,什么是差分约束系统呢?就是给了一些大小条件,然后让你找一个满足的图。这时就要用差分约束了。
怎么做呢?其实很简单,就是直接建图就好,但是要把所有条件变为小于等于号,假如是大于等于就要移项,小于要减一。然后根据这个建图。
相等怎么办?好办,就直接连就行了,长度随意,反正只是判连通。然后跑dfs(或者叫spfa)找负环(最长路),假如有负环就一定不成立。
题目描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述: 农场a比农场b至少多种植了c个单位的作物, 农场a比农场b至多多种植了c个单位的作物, 农场a与农场b种植的作物数一样多。 但是,由于小K的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。 输入输出格式 输入格式: 第一行包括两个整数 n 和 m,分别表示农场数目和小 K 记忆中的信息数目。 接下来 m 行: 如果每行的第一个数是 1,接下来有 3 个整数 a,b,c,表示农场 a 比农场 b 至少多种植了 c 个单位的作物。 如果每行的第一个数是 2,接下来有 3 个整数 a,b,c,表示农场 a 比农场 b 至多多种植了 c 个单位的作物。如果每行的第一个数是 3,接下来有 2 个整数 a,b,表示农场 a 种植的的数量和 b 一样多。 输出格式: 如果存在某种情况与小 K 的记忆吻合,输出“Yes”,否则输出“No”。 输入输出样例 输入样例#1: 复制 3 3 3 1 2 1 1 3 1 2 2 3 2 输出样例#1: 复制 Yes 说明 对于 100% 的数据保证:1 ≤ n,m,a,b,c ≤ 10000。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } struct node { int l,r,nxt,w; }a[25000]; int n,m,len,lst[25000]; void add(int x,int y,int w) { a[++len].l = x; a[len].r = y; a[len].nxt = lst[x]; a[len].w = w; lst[x] = len; } int dis[25000],vis[25000]; bool spfa(int x) { vis[x] = 1; for(int k = lst[x];k;k = a[k].nxt) { int y = a[k].r; if(dis[y] < dis[x] + a[k].w) { dis[y] = dis[x] + a[k].w; if(vis[y] == 1) return 0; if(spfa(y) == 0) return 0; } } vis[x] = 0; return 1; } int main() { int f,a,b,c; read(n);read(m); duke(i,1,m) { read(f); if(f == 1) { read(a);read(b);read(c); add(b,a,c); } else if(f == 2) { read(a);read(b);read(c); add(a,b,-c); } else { read(a);read(b); add(a,b,0); add(b,a,0); } } duke(i,1,n) { add(0,i,0); dis[i] = -INF; } if(spfa(0) == 1) printf("Yes"); else printf("No"); return 0; }