首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

最小生成树之kruskal(并查集)-zoj_1586

2012-11-19 
最小生成树之kruskal(并查集)---zoj_1586????????今天细读了算法导论的21章不相交集合,也就是传说中的并查

最小生成树之kruskal(并查集)---zoj_1586

????????今天细读了算法导论的21章不相交集合,也就是传说中的并查集,有点小收获。原来网上搜的并查集只介绍了路径压缩,今天第一次听说还有按秩合并这回事儿。算法导论上说,同时利用按秩合并和路径压缩技术处理,并查集的操作速度可以大大提升。设有一连串的make-set,find-set,union操作共m个,其中make-set有n个,在渐进意义上,这一连串的操作的时间复杂度为O(m*a(n)),a(n)是一个增长很慢的函数。具体证明不太懂,以后有时间再看。这里值得注意的一点就是union操作包含2个find-set操作和1个link操作。

??????? 再用并查集来分析一下kruskal算法,首先对于带权的边排序的效率为O(ElogE),make-set操作V次,union操作E次,因此总的时间复杂度为(V+E')a(V)+O(ElogE),a(v)=4,E'<V,总的复杂度可以简化为O(V+ElogE)=O(ElogE),换一种表示形式为O(ElogV),因为E<V*V

???????

#include<iostream>#include<algorithm>using namespace std;class union_find_set   {   public:       const static int maximum=1001;    int anc;       int father[maximum];       int count[maximum];     int rank[maximum];          union_find_set()       {           for(int i=0;i<maximum;i++)           {               this->father[i]=i;               this->count[i]=1;    this->rank[i]=0;           }       }       int getFather(int v)       {           if(father[v]==v)           {                  return v;           }           else          {               return  father[v]=getFather(father[v]);           }              }       bool same(int x,int y)       {           return (getFather(x)==getFather(y));       }       bool judge(int x,int y)       {           int fx,fy;           fx=getFather(x);           fy=getFather(y);           if(fx==fy) return false;           else          {               if(rank[x]<rank[y])     {father[fx]=fy;               count[fy]+=count[fx];    }    else if(rank[x]>rank[y])    {   father[fy]=fx;        count[fx]+=count[fy];    }    else    {    father[fx]=fy;               count[fy]+=count[fx];++rank[fy];    }                return true;               }                  }       void init(int max)       {           for(int i=0;i<=max;i++)           {               this->father[i]=i;               this->count[i]=1;      this->rank[i]=0;         }          }   };class node{public:int x,y,cost,flag;node(){flag=0;}};int cmp(const void*a,const void*b){node* A=(node*)a;node* B=(node*)b;if(A->cost>B->cost) return 1;if(A->cost<B->cost) return -1;return 0;}int main(){int n,m;while(cin>>n>>m){node p[m];for(int i=0;i<m;i++){cin>>p[i].x>>p[i].y>>p[i].cost;}qsort(p,m,sizeof(p[0]),cmp);/*for(int i=0;i<m;i++){cout<<p[i].x<<" "<<p[i].y<<" "<<p[i].cost<<endl;}*/union_find_set ufset;ufset.init(n-1);int max=0;for(int i=0;i<m;i++){if(ufset.judge(p[i].x,p[i].y)){p[i].flag=1;if(p[i].cost>max)max=p[i].cost;}}cout<<max<<endl;cout<<n-1<<endl;for(int i=0;i<m;i++){if(p[i].flag==1)cout<<p[i].x<<" "<<p[i].y<<endl;}}}

?

热点排行