[HNOI2005] 狡猾的商人

本来是要做带权并查集才跳到这个题上的。。。但是最后懒省事写了一个差分约束。。。。唉

题解嘛——这题就是普通的差分约束吧??

不会差分约束的话,可以看一下这篇博客,写的很详细很周全。

注意图可能不联通,这个时候要进行多遍spfa。而且注意同一组数据的话不用每次spfa都初始化!!!

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define MAXN 10010
using namespace std;
int T,n,m,s,t,v,edge_number;
int head[MAXN],dis[MAXN],done[MAXN],len[MAXN];
struct Edge{int nxt,to,dis;}edge[MAXN<<1];
inline void add(int from,int to,int dis)
{
	edge[++edge_number].dis=dis;
	edge[edge_number].to=to;
	edge[edge_number].nxt=head[from];
	head[from]=edge_number;
}
inline bool spfa(int x)
{
	queue<int>q;
	q.push(x); done[x]=1; dis[x]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop(); done[u]=0;
		for(int i=head[u];i;i=edge[i].nxt)
		{
			int v=edge[i].to;
			if(dis[v]>dis[u]+edge[i].dis)
			{
				dis[v]=dis[u]+edge[i].dis;
				if(!done[v])
				{
					done[v]=1;
					len[v]=len[u]+1;
					if(len[v]>=n)
						return false;
					q.push(v);
				}
			}
		}
	}
	return true;
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		memset(done,0,sizeof(done));
		memset(dis,0x3f,sizeof(dis));
		memset(len,0,sizeof(len));
		memset(edge,0,sizeof(edge));
		memset(head,0,sizeof(head));
		bool flag=true;
		edge_number=0;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d%d",&s,&t,&v);
			add(t,s-1,v);
			add(s-1,t,-v);	
		}
		for(int i=0;i<=n;i++)
			if(!len[i])
				if(spfa(i)==false)
				{
					printf("false\n");
					flag=false;
					break;
				}
		if(flag==true)
			printf("true\n");
	}
	return 0;
}
posted @ 2018-11-08 17:24  风浔凌  阅读(210)  评论(0编辑  收藏  举报