题意:有一个环形体育场,有n个人坐,给出m个位置关系,A B x表示B所在的列在A的顺时针方向的第x个,在哪一行无所谓,因为假设行有无穷个。

  给出的座位安排中可能有与前面矛盾的,求有矛盾冲突的个数。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm> using namespace std;
const int maxn=;
int n,m,r;
int father[maxn];
int pos[maxn];//pos[i]表示i相对根节点的位置(始终大于0的,顺时针方向) void init(){
for(int i=;i<=n;i++){
father[i]=i;
pos[i]=;
}
}
//查找父节点的时候,同步更新子节点相对更节点的位置
int find_root(int x){
if(father[x]==x)
return x;
int fa=father[x];
father[x]=find_root(father[x]);
pos[x]=(pos[x]+pos[fa])%;
return father[x];
} void Union(int fa,int fb){
father[fb]=fa;
}
int main()
{
int a,b,x;
while(scanf("%d%d",&n,&m)!=EOF){
r=;
init();
for(int i=;i<=m;i++){
scanf("%d%d%d",&a,&b,&x);
int fa=find_root(a);
int fb=find_root(b);
if(fa!=fb){
Union(fa,fb);
/*
b相对a的顺时针位置为x,b相对父节点fb的位置为pos[b],则fb相对b的位置为-pos[b],
a相对父节点fa的位置为pos[a]。
fb相对a的位置为-pos[b]+x,fb相对fa的位置即为(-pos[b]+a+pos[a],
这里为防止出现负数,加了300
*/
pos[fb]=(x-pos[b]+pos[a]+)%;
}
else{
/*
b相对于a的位置
设a、b的根节点为f,则相对a的位置为-pos[a],b相对f的位置为pos[b],
则b相对a的位置为(-pos[a]+pos[b]),这里同样为防止出现负数,加了300
*/
int t=(-pos[a]+pos[b]+)%;
if(t!=x){
r++;
}
}
}
printf("%d\n",r);
}
return ;
}

  

04-21 04:32