`
Coco_young
  • 浏览: 120634 次
  • 性别: Icon_minigender_1
  • 来自: 湖南长沙
社区版块
存档分类
最新评论

并查集

阅读更多



题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272


并查集:用来查找元素所在的集合和合并2个不同的集合,如果用上启发式合并和路径压缩的话,能够进一步优化其效率。一般用森林表示法,即同一个集合的元素属于一颗树,其根节点为该集合的代表元素。

启发式合并:即把深度小得树合并到深度大的树上去。
路径压缩:每次查找完一个元素,都把该查找路径上得元素的父指针指向该集合的代表元素。

#include<iostream>
using namespace std;
const int SIZE = 100010;
int p[SIZE];
bool vis[SIZE];

bool input();
void init();//初始化并查集
int Find(int x);
bool Union(int x,int y); 

int main()
{
    //freopen("datain.txt","r",stdin);
    //freopen("dataout.txt","w",stdout);
    while(input());
    return 0;
}


bool input()
{
   int a,b,cnt=0;
   bool ok = true;
   init();
   while(cin>>a>>b,a||b)
   {
       if(a==-1&&b==-1)return false;
       //还要判断是否只有一个集合 
       if(!vis[a])
       {
          cnt++;
          vis[a] = 1;
       }
       if(!vis[b])
       {
          cnt++;
          vis[b] = 1;
       }
       //判断集合内部是否有环 
       if(!Union(a,b))ok = false;
       else{cnt--;}
   }
   if(ok&&(!cnt||cnt==1)) cout<<"Yes"<<endl;
   else cout<<"No"<<endl;
   return true;
}
void init()
{
   for(int i=0;i<SIZE;i++)
   p[i] = i;
   memset(vis,0,sizeof(vis));
}
int Find(int x)
{
   return x==p[x]?x:Find(p[x]);
}
bool Union(int x,int y)
{
     int px = Find(x);
     int py = Find(y);
     if(px==py)return false;
     p[px] = py;
     return true;
}



  • 大小: 6.2 KB
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics