题意:有一个环形体育场,有n个人坐,给出m个位置关系,A B x表示B所在的列在A的顺时针方向的第x个,在哪一行无所谓,因为假设行有无穷个。
给出的座位安排中可能有与前面矛盾的,求有矛盾冲突的个数。
#include#include #include #include using namespace std;const int maxn=50010;int n,m,r;int father[maxn];int pos[maxn];//pos[i]表示i相对根节点的位置(始终大于0的,顺时针方向)void init(){ for(int i=1;i<=n;i++){ father[i]=i; pos[i]=0; }}//查找父节点的时候,同步更新子节点相对更节点的位置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])%300; 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=0; init(); for(int i=1;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]+300)%300; } 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]+300)%300; if(t!=x){ r++; } } } printf("%d\n",r); } return 0;}