pku 3169 Layout

果然,差分约束的构图才是最关键的步骤,spfa的过程基本已经很熟了,用队列实现的话

在加边的时候,理解错了,重复加边了,s[a]-s[b]>=c 跟s[b]-s[a]>=-c 有区别么?天啊,秀逗了,我来了俩个add(a,b,c),add(b,a,-c)………………

题目有三个判断条件,存在负环,则无解,dis[n]=MAXINT,则可以为任意距离

#include<iostream>
#include<queue>
#define MAXINT 9999999
#define MAXN 1010
using namespace std;
int vis[MAXN],cou[MAXN],dis[MAXN],root[MAXN],n,num;
struct edge
{
	int u,w,next;
}e[MAXN*20];
void add(int u,int v,int len)
{
	e[num].u=v;
	e[num].w=len;
	e[num].next=root[u];
	root[u]=num++;
}
bool spfa()
{
	for(int i=1;i<=n;i++)
		dis[i]=MAXINT;
	dis[1]=0;
	memset(vis,0,sizeof(vis));
	memset(cou,0,sizeof(cou));
	vis[1]=cou[1]=1;
	queue<int> Q;
	Q.push(1);
	while(!Q.empty())
	{
		int t=Q.front(),k;
		Q.pop();vis[t]=0;
		for(int j=root[t];j!=-1;j=e[j].next)
		{
			k=e[j].u;
			if(dis[k]>e[j].w+dis[t])
			{
				dis[k]=e[j].w+dis[t];
				if(!vis[k])
				{
					vis[k]=1;
					Q.push(k);
					cou[k]++;
					if(cou[k]>n) return 0;
				}
			}
		}
	}
	return 1;
}
int main()
{
	int m1,m2;
	int a,b,c;
	while(cin>>n>>m1>>m2)
	{
		memset(root,-1,sizeof(root));
		num=0;
		for(int i=0;i<m1;i++)
		{
			cin>>a>>b>>c;
			add(a,b,c);
		}
		for(int i=0;i<m2;i++)
		{
			cin>>a>>b>>c;
			add(b,a,-c);
		}
		if(spfa())
		{
			if(dis[n]!=MAXINT)
			cout<<dis[n]<<endl;
			else cout<<-2<<endl;
		}
		else cout<<-1<<endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/nanke/p/2137728.html