题目描述
小K 是个特么喜欢玩MC 的孩纸。。。
小K 在MC 里面建立很多很多的农场,总共n 个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m 个),以下列三种形式描述:
农场a 比农场b 至少多种植了c 个单位的作物,农场a 比农场b 至多多种植了c 个单位的作物,农场a 与农场b 种植的作物数一样多。但是,由于小K 的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。
输入
第一行包括两个整数n 和m,分别表示农场数目和小K 记忆中的信息的数目
接下来m 行:
如果每行的第一个数是1,接下来有三个整数a,b,c,表示农场a 比农场b 至少多种植了c 个单位的作物
如果每行第一个数是2,接下来有三个整数a,b,c,表示农场a 比农场b 至多多种植了c 个单位的作物
如果每行第一个数是3,接下来有两个整数a,b,表示农场a 种植的数量与b一样多
输出
如果存在某种情况与小K 的记忆吻合,输出“Yes” ,否则输出“No”
样例输入
3 3
3 1 2
1 1 3 1
2 2 3 2
样例输出
Yes
提示
【样例解释】三个农场种植的数量可以为(2,2,1)。
【数据范围与约定】
对于10%的数据,1 <= n ,m<= 10
对于100%的数据,1 <= n,m,a,b,c <= 10000
想法
- 差分约束裸题。。
算法
- 见代码
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#define MAXN 10005
#define INF ~0U>>2
using namespace std;
int n,m,opt,head[MAXN],tot,dist[MAXN],c[MAXN],x,y,z;
bool visit[MAXN],flag[MAXN],f,oka[MAXN];
struct Node
{
int u,v,w,next;
}edge[MAXN<<2];
inline void add(int u,int v,int w)
{
edge[tot].u=u,edge[tot].v=v,edge[tot].w=w,edge[tot].next=head[u],head[u]=tot++;
}
inline bool spfa(int s)
{
queue<int >q;
for (int i=1;i<=n;i++)
dist[i]=INF;
dist[s]=0;
q.push(s);
memset(visit,0,sizeof(visit));
memset(c,0,sizeof(c));
visit[s]=1;
bool ok=true;
while(!q.empty())
{
int x=q.front();q.pop();visit[x]=0;
oka[x]=1;c[x]++;
for (int i=head[x];i!=-1;i=edge[i].next)
{
int y=edge[i].v;
if(dist[y]>dist[x]+edge[i].w)
{
dist[y]=dist[x]+edge[i].w;
if(!visit[y])
{
visit[y]=1;
q.push(y);
c[y]++;
if(c[y]>10)
{
return ok=false;
}
}
}
}
}
return ok;
}
int main()
{
//freopen("farm.in","r",stdin);
//freopen("farm.out","w",stdout);
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,-z);
flag[x]=flag[y]=1;
}
else if(opt==2)
{
scanf("%d%d%d",&x,&y,&z);
add(y,x,z);
flag[x]=flag[y]=1;
}
else
{
scanf("%d%d",&x,&y);
add(x,y,0);
add(y,x,0);
flag[x]=flag[y]=1;
}
}
f=1;
for (int i=1;i<=n;i++)
{
if(flag[i]&&(!oka[i]))
f&=spfa(i);
}
if(f)printf("Yes\n");
else printf("No\n");
return 0;
}