差分约束 or 带权并查集
思路
假如我们给定了 a − > b , a − > c a->b,a->c a−>b,a−>c现在又给你 b − > c b->c b−>c你是不是就可以直接判断这条句子是不是假的了?我们用带权并查集维护两个元素之间的距离,然后每次发现有俩元素在同一个集合 ,就判断一下是不是满足 d [ x ] − d [ y − 1 ] = z d[x]-d[y-1]=z d[x]−d[y−1]=z就好了
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int f[105],d[105];
inline void read(int &x)
{
x=0;int p=1;char ch=getchar();
while (!isdigit(ch)) p=ch=='-'?0:1,ch=getchar();
while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return (void)(x=p?x:-x);
}
inline int find(int x)
{
if (f[x]==0) return x;
int fa=find(f[x]);
d[x]+=d[f[x]];
return f[x]=fa;
}
signed main()
{
int t;read(t);
while (t--)
{
read(n);read(m);
fill(f,f+n+2,0);
fill(d,d+n+2,0);
int p=0,x,y,z;
for (int i=1;i<=m;i++)
{
read(x);read(y);read(z);y++;
int r1=find(x),r2=find(y);
if (r1!=r2)
d[r2]=d[x]-d[y]-z,f[r2]=r1;
else if (d[x]-d[y]!=z) p=1;
}
if (p) puts("false");
else puts("true");
}
return 0;
}