HDU-1272(小希的迷宫)并查集

题目大意:任意两个点之间在不走回头路的状况下只有一条路联通。ios

解题思路:只须要在基础并查集的基础上记录是否造成了回路,而后用一个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; }
相关文章
相关标签/搜索