题目大意:
对于一些黑帮成员,你知道他们某些人不是一个团伙的,并以此判断另外一些人是否属于同一团伙。
思路:
并查集。难点在于对两个节点是否属于同一集合的判断。
代码:
#include<iostream> #include<stdio.h> using namespace std; int n,m,f[100001]; //f[i]表示节点i的父节点。 bool same[100001]; //same[i]=true表示节点i与其父节点属于同一集合。 void init() //初始化 { for(int i=1;i<=n;i++) { f[i]=i; //将每个节点的父节点初始化为其自身。 same[i]=true; //相应地,自身属于同一集合。 } } int find(int x) //找到x的父节点。 { if(x!=f[x]) { int px=f[x]; //px为更新前x的父节点。 f[x]=find(f[x]); if(same[x]&&!same[px]) //px节点已经访问结束,所以same[px]已经被更新,px的父节点和x的父节点相同。 //当前same[x]表示x与px是否属于同一集合,same[px]表示px和x与px新的共同的父节点是否属于同一集合。 same[x]=false; //根据same[x]与same[px]来更新same[x]。更新后的same[x]表示x与新父节点是否属于同一集合。 else if(!same[x]&&!same[px]) same[x]=true; } return f[x]; } void union_set(int x, int y) { int px=find(x); int py=find(y); if(px!=py) { f[px]=py; if(same[x]==same[y]) same[px]=same[px]?false:true; } } int main() { int t; for(scanf("%d",&t);t>0;t--) { scanf("%d%d",&n,&m); init(); for(int i=0;i<m;i++) { char op; int a,b; scanf("\n%c%d%d",&op,&a,&b); if(op=='A') if(find(a)!=find(b)) printf("Not sure yet.\n"); else if(same[a]==same[b]) printf("In the same gang.\n"); else printf("In different gangs.\n"); else union_set(a,b); } } }
背景好看
主题不错哦