3.小K的农场(farm.pas/cpp/c)
【题目描述】
小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述:农场a比农场b至少多种植了c个单位的作物,农场a比农场b至多多种植了c个单位的作物,农场a与农场b种植的作物数一样多。但是,由于小K的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。
【输入格式】 farm.in
第一行包括两个整数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一样多。
【输出格式】 farm.out
如果存在某种情况与小K的记忆吻合,输出“Yes”,否则输出“No”。
【样例输入】
3 3
3 1 2
1 1 3 1
2 2 3 2
【样例输出】
Yes
样例解释:三个农场种植数量可以为(2,2,1)。
对于100%的数据 1<=n,m,a,b,c<=10000.
查分约束……
1代表a-b>=c,即b-a<=-c
2代表a-b<=c
3是a=b即a-b<=0且b-a<=0
然后就是建图了
1、2插单向边,3插双向边
#include<cstdio> #include<iostream> #include<cstring> #define S 0 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct edge{ int to,next,v; }e[200001]; int cnt; int head[200001]; inline void ins(int u,int v,int w) { e[++cnt].v=w; e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } inline void insert(int u,int v,int w) { ins(u,v,w); ins(v,u,-w); } int n,m,ans; bool flag[50001]; int dist[50001]; inline void spfa(int x) { flag[x]=1; for (int i=head[x];i;i=e[i].next) { if (dist[x]+e[i].v<dist[e[i].to]) { if (flag[e[i].to]) {ans=1;return;} dist[e[i].to]=dist[x]+e[i].v; spfa(e[i].to); } } flag[x]=0; } int main() { freopen("farm.in","r",stdin); freopen("farm.out","w",stdout); memset(dist,127/3,sizeof(dist)); n=read();m=read(); int opr,x,y,z; for (int i=1;i<=n;i++) ins(S,i,0); for (int i=1;i<=m;i++) { opr=read(); x=read(); y=read(); if (opr!=3) z=read(); if (opr==1) ins(y,x,-z); if (opr==2) ins(x,y,z); if (opr==3) insert(x,y,0); } dist[S]=0; spfa(S); if (ans) printf("No"); else printf("Yes"); }