poj2492(并查集)

 

今天一早AC了两道简单的并查集,2429和1703,这两道的思路几乎完全一样。用一个数组表示根节点,再用一个表示其与根节点的关系就OK了,每次合并与压缩路径的时候注意关系的更新。

 

 

虫子的同性恋,跟食物链是一样的,不过这个只有两个关系,比那个简单多了。

 

#include "iostream" #include "stdio.h" using namespace std; int n,p[2002],r[2002];// r[i] 0代表r[i]与i同性, 1代表i与r[i]异性 int find(int x) { int temp=p[x]; if(x==p[x]) return x; p[x]=find(p[x]); r[x]=r[temp]==0 ? r[x]:1-r[x]; return p[x]; } int make() { int i; for(i=0; i<=n; i++) { p[i]=i; r[i]=0; } } int Union(int x,int y,int rx,int ry) { p[ry]=rx; r[ry]= r[x]==r[y] ? 1:0; } int main() { int i,j,m,a,b,rx,ry,flag,count=1,t; scanf("%d",&t); while(t--) { flag=0; scanf("%d %d",&n,&m); make(); while(m--) { scanf("/n%d %d",&a,&b); // cin>>a>>b; rx=find(a); ry=find(b); if(rx==ry && r[a]==r[b]) flag = 1; else Union(a,b,rx,ry); } if(flag==1) printf("Scenario #%d:/nSuspicious bugs found!/n",count++); else printf("Scenario #%d:/nNo suspicious bugs found!/n",count++); printf("/n"); } system("pause"); return 0; }

 

1703 抓犯罪分子的

#include "stdio.h" #include "iostream" using namespace std; int p[100002],rank[100002],gang[100002];//0为与p[x] 相同,1为不同 int n; int make() { int i; for(i=0; i<=n; i++) { p[i]=i; gang[i]=0; mark[i]=0; } } int find(int x) { int temp = p[x]; if(p[x]!=x) { p[x] = find(p[x]); gang[x] = gang[temp]==0?gang[x]:(1-gang[x]); } return p[x]; } int part(int x,int y) { int rx=find(x); int ry=find(y); p[ry]=rx; gang[ry] = gang[x]==gang[y] ? 1:0; // } int main() { int x,y,m,t,a,b; char c; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&m); make(); while(m--) { cin>>c; scanf("%d%d",&a,&b); if (c=='D') part(a,b); else { if (find(a)==find(b)) { if (gang[a]==gang[b]) cout<<"In the same gang."<<endl; else cout<<"In different gangs."<<endl; } else cout<<"Not sure yet."<<endl; } } } // system("pause"); return 0; }

 

 

 

 

 

你可能感兴趣的:(poj2492(并查集))