P1993 小K的农场

橙三吉。 提交于 2019-11-29 17:55:31

题目描述

小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。

思路

源自:five20

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=50010,oo=1e9;

bool vis[N];
int n,m,tot;
int to[N],hed[N],w[N];
int sum[N],dis[N],nxt[N];

void add(int u,int v,int c) {
	to[++tot]=v;
	nxt[tot]=hed[u];
	hed[u]=tot;
	w[tot]=c;
}

bool spfa(int u) {
	vis[u]=1;
	for(int i=hed[u]; i; i=nxt[i])
		if(dis[to[i]]<dis[u]+w[i]) {
			dis[to[i]]=dis[u]+w[i];
			if(vis[to[i]])
				return false;
			if(!spfa(to[i]))
				return false;
		}
	vis[u]=0;
	return true;
}

int main () {
	scanf("%d%d",&n,&m);
	int f,u,v,w;
	while(m--) {
		scanf("%d%d%d",&f,&u,&v);
		if(f==1) {
			scanf("%d",&w);
			add(u,v,w);
		}
		if(f==2) {
			scanf("%d",&w);
			add(u,v,-w);
		}
		if(f==3) {
			add(u,v,0);
			add(v,u,0);
		}
	}
	for(int i=1; i<=n; i++) {
		add(0,i,0);
		dis[i]=-oo;
	}
	if(!spfa(0))
		printf("No\n");
	else
		printf("Yes\n");
	return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!