[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;
}