P1993 小 K 的农场

小 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 1n,m,a,b,c5×103
用SPFA

#include
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;
} 

你可能感兴趣的:(题解,编程万能专栏(什么都有),算法,图论)