比赛
题目
有一个圆环,知道两个点的相对关系,求至少有多少个关系是错的。
分析
用并查集,f表示最早的祖先,dis表示到最早的祖先的距离。
d
i
s
[
v
]
=
(
(
d
i
s
[
x
]
−
d
i
s
[
y
]
+
w
+
300
)
m
o
d
  
300
)
dis[v]=((dis[x]-dis[y]+w+300) \mod {300})
dis[v]=((dis[x]−dis[y]+w+300)mod300)
当在同一个集合内并且距离不同,视为假关系。
代码
#include <cstdio>
#include <cctype>
using namespace std;
int n,m,f[100001],dis[100001],ans;
int in(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int getf(int u){
if (f[u]==u) return u;
int fa=f[u];
f[u]=getf(f[u]);
dis[u]=(dis[u]+dis[fa])%300;//修改距离
return f[u];
}
int main(){
n=in(); m=in();
for (int i=1;i<=n;i++) f[i]=i;
for (int i=1;i<=m;i++){
int x=in(),y=in(),w=in();
int u=getf(x),v=getf(y);
if (u!=v){
f[v]=u;
dis[v]=((dis[x]-dis[y]+w+300)%300);//加入集合
}
else if ((dis[x]+w)%300!=dis[y]) ans++;//假关系
}
return !printf("%d",ans);
}