1202: [HNOI2005]狡猾的商人
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2166 Solved: 1027
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
3 3
1 2 10
1 3 -5
3 3 -15
5 3
1 5 100
3 5 50
1 2 51
Sample Output
false
解题思路:
带权并查集。确定和根的关系,如果当前两个根不同则合并,相同则判断是否存在矛盾if (dis[t[i]]-dis[s[i]-1]!=-v[i])
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int w;
int n,m;
int s[1001];
int t[1001];
int v[1001];
int dis[201];
int f[201];
int find(int o)
{
if (f[o]==o)
{
dis[o]=0; return o;
}
int u=f[o];
f[o]=find(f[o]);
dis[o]+=dis[u];
return f[o];
}
void untion(int x,int y,int f1,int f2,int v)
{
f[f1]=f2;
dis[f1]=v+dis[y]-dis[x];
}
int main()
{
scanf("%d",&w);
for (int y=1;y<=w;++y)
{
scanf("%d %d",&n,&m);
for (int i=0;i<=n;i++)
{
f[i]=i; dis[i]=0;
}
bool mg=true;
for (int i=1;i<=m;++i)
{
scanf("%d %d %d",&s[i],&t[i],&v[i]);
int f1=find(s[i]-1); int f2=find(t[i]);
if (f1==f2)
{
if (dis[t[i]]-dis[s[i]-1]!=-v[i])
{
mg=false;
break;
}
}else
{
untion(s[i]-1,t[i],f1,f2,v[i]);
}
}
if (mg) cout<<"true"<<endl;else
cout<<"false"<<endl;
}
}