这个题是一个典型的并查集,在路径压缩的时候要注意维护儿子与父亲的关系,在合并两个集合时也需要维护关系 这里有篇文章写得很详细。http://apps.hi.baidu.com/share/detail/16059767 /* * File: main.cpp * Author: mi * * Created on 2011年2月20日, 下午3:06 */ #include <cstdlib> #include <stdio.h> #define N 50005 using namespace std; /* * */ int father[N],rank[N]; void make_set(int n) { int i; for(i=0;i<n;i++) { father[i]=i; rank[i]=0; } } int find_set(int x) { int temp; temp=father[x]; if(x!=father[x]) { father[x]=find_set(father[x]); rank[x]=(rank[x]+rank[temp]+3)%3; } return father[x]; } void Union(int x,int y,int rootx,int rooty,int d) { father[rooty]=rootx; rank[rooty]=(rank[x]-d-rank[y]+3)%3; } int main(int argc, char** argv) { int n,k,ans=0; scanf("%d%d",&n,&k); make_set(n); while(k--) { int d,a,b; scanf("%d%d%d",&d,&a,&b); if(a>n||b>n) ans++; else if(a==b&&d==2) ans++; else { int rootx,rooty; rootx=find_set(a),rooty=find_set(b); if(rootx==rooty) { if(d==1&&rank[a]!=rank[b]) ans++; else if(d==2&&(rank[a]-rank[b]+3)%3!=1) ans++; } else Union(a,b,rootx,rooty,d-1); } } printf("%d/n",ans); return 0; }