[Bzoj1731]排队布局

洛谷上的翻译是真的哲学♂♂♂

非常van的题目传送门♂♂♂

个人认为这题充其量也就是个蓝(nan)题,首先处理-1的情况,-1的情况是不等式组无解,按照差分约束的规则,无解说明出现了负环,先跑一遍以0为源点的SPFA判断有无负环即可。再来处理-2的情况,结果为-2就说明1号和n号节点不存在直接的或间接的约束关系,所以我们跑一遍以1为源点SPFA看1到n连不连通即可。最后如果答案不为-1和-2,那么dist[n]就是答案啦。~~~♂♂♂♂♂♂♂♂♂

参考程序如下:

#include<iostream>
#include<cstring>
#include<queue>
#define inf 336860180
using namespace std;
int n,ml,md,v[50005],w[50005],head[50005],nxt[50005],cnt,ring[100001],dist[100001],a,b,d;
bool vis[100001];
void add(int a,int b,int c)
{
	v[++cnt]=b;
	w[cnt]=c;
	nxt[cnt]=head[a];
	head[a]=cnt;
}
bool spfa(int s)
{
	memset(dist,20,sizeof(dist));
	memset(ring,0,sizeof(ring));
	dist[s]=0;
	queue<int>q;
	q.push(s);
	vis[s]=1;
	while(!q.empty())
	{
		int c=q.front();
		q.pop();
		vis[c]=0;
		ring[c]++;
		if(ring[c]==n)return 1;
		for(int i=head[c];i;i=nxt[i])
		{
			int y=v[i];
			if(dist[y]>dist[c]+w[i])
			{
				dist[y]=dist[c]+w[i];
				if(!vis[y])
				{
					q.push(y);
					vis[y]=1;
				}
			}
		} 
	}
	return 0;
}
int main()
{
	cin>>n>>ml>>md;
	for(int i=1;i<=ml;i++)
	{
		cin>>a>>b>>d;
		add(a,b,d);
	}
	for(int i=1;i<=md;i++)
	{
		cin>>a>>b>>d;
		add(b,a,-d); 
	}
	for(int i=1;i<=n;i++)add(0,i,0);
	if(spfa(0))
	{
		cout<<"-1";
		return 0;
	}
	spfa(1);
	if(dist[n]==inf)
	{
		cout<<"-2";
		return 0;
	}
	cout<<dist[n]<<endl;
	return 0; 
} 

  

猜你喜欢

转载自www.cnblogs.com/szmssf/p/11093665.html