小K的农场,洛谷之提高历练地,较复杂图论II

正题

      第一题:小K的农场

      这道题的三个形式分别可以表示为:Ta-Tb>=c;Ta-Tb<=c;Ta-Tb=0;

      相当于就是判断是否有解,我们把他们全部变成大于号,可以知道:Ta-Tb>=c;Tb-Ta>=-c;Ta-Tb>=0;

      Tb-Ta>=0;

      我们从b到a建一条c边,a到b建一条-c的边,b到a和a到b建一条0的边。

      我们跑一边SPFA,判断是否有正环即可,最长路求解。

代码<话说卡差分约束SPFA不是一天两天了>

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
using namespace std;

int n,m;
struct edge{
	int y,c,next;
}s[20010];
int len=0;
int first[10010];
queue<int> f;
int d[10010][2];
bool tf[10010];

void ins(int x,int y,int c){
	len++;
	s[len].y=y;s[len].c=c;s[len].next=first[x];first[x]=len;
}

bool SPFA(int q){
	tf[q]=true;
	d[q][0]=0;
	d[q][1]=0;
	f.push(q);
	bool we=true;
	while(!f.empty()){
		int x=f.front();
		f.pop();
		for(int i=first[x];i!=0;i=s[i].next){
			int y=s[i].y;
			if(d[y][0]>d[x][0]+s[i].c){
				if(tf[y]==false){
					tf[y]=true;	
					f.push(y);
				}	
				else if(d[y][1]==s[i].c) we=false;
				d[y][0]=d[x][0]+s[i].c;
				d[y][1]=s[i].c;
			}
		}
	}
	return we;
}

int main(){
	memset(d,63,sizeof(d));
	scanf("%d %d",&n,&m);
	int x,y,c;
	for(int i=1;i<=m;i++){
		int t;
		scanf("%d %d %d",&t,&x,&y);
		if(t==1 || t==2) scanf("%d",&c);
		if(t==1) ins(x,y,-c);
		else if(t==2) ins(y,x,c);
		else ins(x,y,0),ins(y,x,0);
	}
	for(int i=1;i<=n;i++){
		if(tf[i]==false)
			if(!SPFA(i)){
				printf("No\n");
				return 0;
			}
	}
	printf("Yes");
}

阅读更多
版权声明: https://blog.csdn.net/Deep_Kevin/article/details/79948928
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭