小 K 的农场
题目描述
小 K 在 MC 里面建立很多很多的农场,总共 n n n 个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共 m m m 个),以下列三种形式描述:
- 农场 a a a 比农场 b b b 至少多种植了 c c c 个单位的作物;
- 农场 a a a 比农场 b b b 至多多种植了 c c c 个单位的作物;
- 农场 a a a 与农场 b b b 种植的作物数一样多。
但是,由于小 K 的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。
输入格式
第一行包括两个整数 n n n 和 m m m,分别表示农场数目和小 K 记忆中的信息数目。
接下来 m m m 行:
- 如果每行的第一个数是 1 1 1,接下来有三个整数 a , b , c a,b,c a,b,c,表示农场 a a a 比农场 b b b 至少多种植了 c c c 个单位的作物;
- 如果每行的第一个数是 2 2 2,接下来有三个整数 a , b , c a,b,c a,b,c,表示农场 a a a 比农场 b b b 至多多种植了 c c c 个单位的作物;
- 如果每行的第一个数是 3 3 3,接下来有两个整数 a , b a,b a,b,表示农场 a a a 种植的的数量和 b b b 一样多。
输出格式
如果存在某种情况与小 K 的记忆吻合,输出 Yes
,否则输出 No
。
样例 #1
样例输入 #1
3 3
3 1 2
1 1 3 1
2 2 3 2
样例输出 #1
Yes
提示
对于
100
%
100\%
100% 的数据,保证
1
≤
n
,
m
,
a
,
b
,
c
≤
5
×
1
0
3
1 \le n,m,a,b,c \le 5 \times 10^3
1≤n,m,a,b,c≤5×103。
用SPFA
#include<bits/stdc++.h>
using namespace std;
struct aty{
int v,w;
};
vector<aty> E[5005];
queue<int> q;
int n,m,dis[5005],u,v,w,fw[5005],op;
bool vis[5005];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&u,&v,&w);
E[u].push_back({v,-w});
}else if(op==2){
scanf("%d%d%d",&u,&v,&w);
E[v].push_back({u,w});
}else{
scanf("%d%d",&u,&v);
E[u].push_back({v,0});
E[v].push_back({u,0});
}
}
for(int i=1;i<=n;i++){
E[0].push_back({i,0});
dis[i]=INT_MAX;
}
dis[0]=0;
fw[0]=1;
q.push(0);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int i=0;i<E[u].size();i++){
if(dis[u]+E[u][i].w<dis[E[u][i].v]){
dis[E[u][i].v]=dis[u]+E[u][i].w;
fw[E[u][i].v]++;
if(fw[E[u][i].v]>n+1){
printf("No");
return 0;
}
q.push(E[u][i].v);
vis[E[u][i].v]=1;
}
}
}
printf("Yes");
return 0;
}