`
plussai
  • 浏览: 88728 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

最小生成树之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;
		}
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics