HDU-1272(小希的迷宫)并查集
作者:互联网
题目大意:任意两个点之间在不走回头路的情况下只有一条路联通。
解题思路:只需要在基础并查集的基础上记录是否形成了回路,然后用一个set记录节点与边是否满足对应的关系就可以了。
#include<iostream> #include<set> #include<algorithm> using namespace std; const int N=100005; int f[N];//f数组记录根节点 int Urank[N];//记录根节点的秩,按秩合并的需要 int flag,grah;//当flag为1时,表示形成了环 set<int> s;//记录节点的集合 void init(int x)//初始化函数 { for(int i=0;i<=x;i++) { f[i]=i; Urank[i]=0; } flag=0;//初始是无环的 grah=1; } int U_find(int x)//非递归的路径压缩查询 { int r,j,k; r=x; while(r!=f[r]) { r=f[r]; } k=x; while(k!=r) { j=f[k]; f[k]=r; k=j; } return r; } void U_merge(int x,int y)//按秩合并 { x=U_find(x); y=U_find(y); if(x!=y) { if(Urank[x]<Urank[y]) { f[x]=y; }else { f[y]=x; if(Urank[x]==Urank[y])Urank[x]++; } }else flag=1;//当合并的两者根节点相同时,说明形成了环 } int main() { int a,b; while(cin>>a>>b)//多组输入,输入每一组的第一对数据 { init(N);//初始化,因为已经输入一对了,所以边被初始化成1 if(a==0&&b==0)//当a与b都为0时,说明是空树,空树也满足条件 { cout<<"Yes"<<endl; } if(a==-1&&b==-1)//结束条件 { break; } s.insert(a); s.insert(b);//将两点插入集合中 if(!flag)//只要没有出现环,就合并两点 { U_merge(a,b); } while(1)//在符合继续输入的条件下,开始读完后续的数据 { cin>>a>>b; if(a==0&&b==0)//单组数据终止条件 { break; }else { s.insert(a); s.insert(b); if(!flag) { U_merge(a,b); } grah++;//上述操作同理,只不过要记得每次都要把边的数量加一 } } if(!flag&&s.size()==grah+1)//没有形成环且节点数等于边数+1的情况下满足条件 { cout<<"Yes"<<endl; }else { cout<<"No"<<endl; } s.clear();//清空集合 } return 0; }
标签:HDU,小希,int,查集,grah,flag,&&,include,节点 来源: https://www.cnblogs.com/cloudplankroader/p/10654409.html