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

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

分析:反向并查集求联通分量,假设起始各个点都不连通,接着从最后一条边开始添加,如果新加入的边联通了两个联通块,则联通分量减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;
}
时间: 2024-10-15 05:42:21

HDU ACM 4496 D-City ->并查集+逆向的相关文章

HDU ACM 1856 More is better-&gt;并查集

解析:又是一个并查集. 1.题意:王老师需要一些男生帮他做事.要求男生之间都是朋友关系,可以直接的,也可以间接地.最多可以挑选出几个男生(最少挑一个)? 2.并查集,求所有集合中最大集合的元素个数. 3.要注意一个地方是:当n=0时,要输出1. #include<iostream> #include<algorithm> using namespace std; int p[10000001],num[10000001]; bool Init(int n) //一开始指向自己 {

HDU ACM 1232 畅通工程-&gt;并查集

分析: 地图上有若干个城镇,城镇都可以看作点,然后给出哪些城镇之间是直接相连的.要解决的是整幅图的连通性问题.比如两个点,判断它们是否连通,或者整幅图共有几个连通分支,就是被分成多少个互相独立的块.因此这个题实质就是求有几个连通分支:如果是1个,则整幅图都连起来了:如果是2个,只要再修1条路,在两个分支中各选一个点,连起来,这样所有点就连起来了:3个连通分支,则只需再修两条......,这样就可以使用并查集很好的解决了. #include<iostream> using namespace s

HDU 4496 D-City (并查集)

题意:给你n个点m条边,问删除前i条边后有多少个连通分块. 思路:从后往前操作,从后往前添加i条边等于添加完m条边后删掉前m-i条边,可知刚开始没有边,所以sum[m]=n; #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 100010

HDU 3635 延缓更新的并查集

Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2839    Accepted Submission(s): 1097 Problem Description Five hundred years later, the number of dragon balls will increase unexpecte

HDU 3461 Code Lock(并查集的应用+快速幂)

* 65536kb,只能开到1.76*10^7大小的数组.而题目的N取到了10^7,我开始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 其实路径压缩也可以不用.............  题目的大意: 一个密码锁上有编号为1到N的N个字母,每个字母可以取26个小写英文字母中的一个.再给你M个区间[L,M],表示该区间的字母可以一起同步"增加"(从'a'变为'b'为增1,'z'增1为'a').假如一组密码按照给定的区间进行有限

HDU 1558 Segment set (并查集+线段非规范相交)

题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. 1 //1558 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <cmath> 6 #define eps 1e-8 7 #define zero(x) (((x) > 0 ? (x) : (-x)) < e

HDU 4496 D-City —— (并查集的应用)

给出n个点和m条边,一条一条地删除边,问每次删除以后有多少个联通块. 分析:其实就是并查集的应用,只是前一阵子一直做图论思路一直囿于tarjan了..方法就是,记录每一条边,然后从最后一条边开始不断的加边,如果用并查集来判断联通块有没有减少即可. 代码如下: 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <set> 5 using namespace

HDU 3407.Zjnu Stadium 加权并查集

Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3726    Accepted Submission(s): 1415 Problem Description In 12th Zhejiang College Students Games 2007, there was a new stadium built

hdu 1232 畅通工程(并查集算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1232 畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31088    Accepted Submission(s): 16354 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条