码迷,mamicode.com
首页 > 其他好文 > 详细

HDU ACM 4496 D-City ->并查集+逆向

时间:2015-05-21 00:05:44      阅读:427      评论:0      收藏:0      [点我收藏+]

标签:c   c++   acm   算法   编程   

题意:给定一张图,按照输入的边逐个删除,求每次删除一条边之后图的联通块数量。

分析:反向并查集求联通分量,假设起始各个点都不连通,接着从最后一条边开始添加,如果新加入的边联通了两个联通块,则联通分量减1(保存在数组中),最后正序输出结果即可。


#include<iostream>   
#include<algorithm>     
using namespace std;    
    
int p[10005];  
  
struct EDGE  
{  
    int x,y;  
} edge[100005];
int ans[100005];
  
bool Init(int n)  
{    
    for(int i=0;i<n;i++)    
        p[i]=i;    
    return true; 
}    
    
int Find(int x)   
{    
    int r,i,j;    
    
    r=x;    
    while(r!=p[r]) r=p[r];  
    
    i=x;    
    while(i!=p[i])   //路径压缩  
    {    
        j=p[i];    
        p[i]=r;    
        i=j;    
    }    
    return i;
}    
    
bool Merge(int x,int y)  
{    
    int tx,ty;    
    
    tx=Find(x);    
    ty=Find(y);    
    
    if(tx==ty) return false;    
    p[tx]=ty;    
    return true;    
}    
    
int main()      
{  
    int N,M,i,u,v,sum;

	while(scanf("%d%d",&N,&M)==2)
	{
		Init(N);
		for(i=0;i<M;i++)
			scanf("%d%d",&edge[i].x,&edge[i].y);

		sum=N;
		for(i=M-1;i>=0;i--)
		{
			ans[i]=sum;
			u=Find(edge[i].x);
			v=Find(edge[i].y);
			if(u!=v)              //合并两个联通快,连通分量减1.
			{
				Merge(u,v);
				sum--;
			}
		}
		for(i=0;i<M;i++)
			printf("%d\n",ans[i]);
	}
    return 0;      
}


HDU ACM 4496 D-City ->并查集+逆向

标签:c   c++   acm   算法   编程   

原文地址:http://blog.csdn.net/a809146548/article/details/45876669

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!