前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小K的农场 差分约束

小K的农场 差分约束

作者头像
用户2965768
发布2019-04-18 15:29:51
3760
发布2019-04-18 15:29:51
举报
文章被收录于专栏:wym

小K的农场

  跑最长路

1 a-b>=c  建立b到a权值为c的路

2 a-b<=c----->  b-a>=-c  建立a到b权值为-c的路

3 a=b   建立a到b,b到a的双向权值为0的路

问满足以上所有条件的情况是否存在,则就是问是否存在负环。改写spfa为dfs.

indfs[ i ]表示 i 是否正在被dfs, book[ i ]表示 i 点是否访问过。如果一个点在dfs且再次回到路径小于上次就存在环。

代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
struct Edge{
	int v,w,nxt;
};
int cnt,head[100000];
Edge edge[100000];
int book[10005],dis[10005],indfs[100005],n,m;
int read(){
	int x=0,dign=1;
	char c = getchar();
	while(c<'0'||c>'9'){
		if(c=='-')dign=-1;
		c = getchar();
	}
	while(c>='0'&&c<='9'){
		x = x*10 + c - '0';
		c = getchar();
	}
	return x*dign;
}
void add(int u,int v,int w){
	cnt++;
	edge[cnt].v = v; edge[cnt].w = w;
	edge[cnt].nxt = head[u];
	head[u] = cnt;
}
bool spfa(int u){
		indfs[u] = 1;
		for(int w,v,i=head[u];i;i=edge[i].nxt){
			v = edge[i].v; w = dis[u] + edge[i].w;
			if(!book[v]||dis[v]<w){
				if(indfs[v])return false;//一个点通过一段路径回到这个点比之前更优存在环 
				book[v] = 1;
				dis[v]=w;
				if(!spfa(v))return false;
			}	
		}
		indfs[u] = 0;
		return true; 
}
int main()
{
	n = read(); m = read();
	for(int i=0;i<=n;i++)add(0,i,0);
	
	for(int i=0;i<m;i++){
		int t,a,b,c;
		t = read();
		if(t==3){
			a = read(); b = read();
			add(b,a,0);
			add(a,b,0);
		}else if(t==1){
			a = read(); b = read(); c = read();
			add(b,a,c);
		}else{
			a = read(); b = read(); c = read();
			add(a,b,-c);	
		}
	}
	for(int i=1;i<=n;i++)dis[i] = -1;
	dis[0] = 0; book[0] = 1;

	if(!spfa(0))printf("No\n");
	else printf("Yes\n"); 
	return 0;
 } 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年04月08日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档