题意 :
给一些奶牛之间身高的差值,判断是否能够成立。
给定的关系式 Hj - Hi = A , 没有不等式,不好差分约束QAQ,但是可以把它看成 Hj - Hi >= A 和 Hj - Hi <= A 同时成立,跑两遍spfa……
这里给的是另一种算法,利用带权并查集来维护各个奶牛之间的关系,已有关系的两个奶牛可以通过并查集来得到身高差来和提供的身高差对比来判断新给的关系是否成立。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fa[100010],dis[100010]; // dis[i] 记录的 i 与 i 的祖先结点的高度差
int find(int x)
{
if(fa[x] == x)
return x;
int fx = fa[x];
fa[x] = find(fa[x]);
dis[x] += dis[fx];
return fa[x];
}
int n,m;
void init()
{
for(int i = 1 ; i <= n ; i ++)
dis[i] = 0 , fa[i] = i;
}
int main()
{
int w;
scanf("%d",&w);
for(int k = 1 ; k <= w ; k ++)
{
scanf("%d%d",&n,&m);
init();
bool flag = 1;
for(int i = 1 ; i <= m ; i ++)
{
int s,t,v;
scanf("%d%d%d",&s,&t,&v);
if(!flag)
continue;
int fs = find(s) , ft = find(t); // 找爹环节
if(fs == ft) // 是否有关系
{
if(dis[s] - dis[t] != v) // 有关系且不与现在提供的 v 符合 ;设 h[i] 为第 i 头牛的高度 , f 为 s 和 t 的祖先 , s 如果与 t 同祖先 则 h[f] - h[s] == dis[s] ; h[f] - h[t] == dis[t] 又 ∵ h[t] - h[s] = v ; ∴ dis[s] - dis[t] == v
flag = 0;
}
else // 两个点之前根本没有关系
{
fa[fs] = ft;
dis[fs] = dis[t] - dis[s] + v;
} // 合并 s 和 t
}
if(flag)
puts("Bessie's eyes are good");
else
puts("Bessie is blind.");
}
return 0;
}
传送门 : codevs4246