hdu4496 D-City(反向并查集)

转载请注明出处:http://blog.csdn.net/u012860063

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

D-City

Problem Description

Luxer is a really bad guy. He destroys everything he met.

One day Luxer went to D-city. D-city has N D-points and M D-lines. Each D-line connects exactly two D-points. Luxer will destroy all the D-lines. The mayor of D-city wants to know how many connected blocks of D-city left after Luxer destroying the first K D-lines
in the input.

Two points are in the same connected blocks if and only if they connect to each other directly or indirectly.

Input

First line of the input contains two integers N and M.

Then following M lines each containing 2 space-separated integers u and v, which denotes an D-line.

Constraints:

0 < N <= 10000

0 < M <= 100000

0 <= u, v < N.

Output

Output M lines, the ith line is the answer after deleting the first i edges in the input.

Sample Input

5 10
0 1
1 2
1 3
1 4
0 2
2 3
0 4
0 3
3 4
2 4

Sample Output

1
1
1
2
2
2
2
3
4
5

Hint

The graph given in sample input is a complete graph, that each pair of vertex has an edge connecting them, so there‘s only 1 connected block at first.
The first 3 lines of output are 1s  because  after  deleting  the  first  3  edges  of  the  graph,  all  vertexes  still  connected together.
But after deleting the first 4 edges of the graph, vertex 1 will be disconnected with other vertex, and it became an independent connected block.
Continue deleting edges the disconnected blocks increased and finally it will became the number of vertex, so the last output should always be N.

Source

2013
ACM-ICPC吉林通化全国邀请赛——题目重现

/*题目不是很难,只需要逆向思考(正向行不通的时候,我们不防换一条路
试试,生活亦是如此);我们可以逆向认为所有的点全是独立的,因为正
向的时候去掉其中某条边的,独立的点不一定会增多(去掉这条边后还有
其他边间接的相连),所以当我们逆向思考的时候,只会在增加某一条边
时减少独立的点(也就是联通的点增多),这样只会在他之后才会有可能
有某条边的操作是“无效”的(联通的点不变);*/
//并查集!
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

#define M 10047
int father[M];
int ans[M];//记录独立的点数
struct node
{
	int l,r;
}P[100047];

int find(int x)
{
	return x == father[x]?x:father[x]=find(father[x]);
}

int main()
{
	int n, m, i, j, t;
	while(~scanf("%d%d",&n,&m))
	{
		t = n;
		for(i = 0; i <= n; i++)
		{
			father[i] = i;
		}
		for(i = m-1; i >= 0; i--)//注意此处的i是从大到小的,把去掉边的操作逆向存储在结构体中
		{						 //这样就能达到上面说得逆向思考
			scanf("%d%d",&P[i].l,&P[i].r);
		}
		for(i = 0; i < m; i++)   //因为记录的边已经逆向,这里就不再需要
		{
			int f1 = find(P[i].l);
			int f2 = find(P[i].r);
			if(f2 != f1)
			{
				father[f1] = f2;
				t--;            //当有新增的边使独立的点减少的时候
			}
			ans[i] = t;
		}
		for(i = m - 2; i >= 0; i--)
		{
			printf("%d\n",ans[i]); //逆向输出
		}
		printf("%d\n",n);
	}
	return 0;
}

hdu4496 D-City(反向并查集)

时间: 2024-08-18 19:48:03

hdu4496 D-City(反向并查集)的相关文章

hdu 4496 并查集 反向并查集 水题 D-City

觉得这道题以后可以和优先队列结合起来 嗯 就是说依次去掉前n条路求连通块数量 处理的时候  只要每次merge发现父亲不相等 然后进到里面合并的时候 num-- wa了好几次是因为最后输出的时候开了点的数量大小的数组而不是操作数量数组 orz D-City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 5334    Accepted

HDU ACM 4496 D-City -&gt;并查集+逆向

题意:给定一张图,按照输入的边逐个删除,求每次删除一条边之后图的联通块数量. 分析:反向并查集求联通分量,假设起始各个点都不连通,接着从最后一条边开始添加,如果新加入的边联通了两个联通块,则联通分量减1(保存在数组中),最后正序输出结果即可. #include<iostream> #include<algorithm> using namespace std; int p[10005]; struct EDGE { int x,y; } edge[100005]; int ans[

并查集 专题总结

一.题目类型: 1.普通并查集: poj2513 Colored Sticks hdu1198 Farm Irrigation SCAU 1138 代码等式 Gym - 100676F Palindrome Codeforces Round #363 (Div. 2) D. Fix a Tree Codeforces Round #376 (Div. 2) C. Socks 2.种类并查集: HDU3038 How Many Answers Are Wrong POJ1182 食物链 POJ24

P3144 [USACO16OPEN]关闭农场Closing the Farm_Silver(并查集反向)

题目描述 Farmer John and his cows are planning to leave town for a long vacation, and so FJ wants to temporarily close down his farm to save money in the meantime. The farm consists of NNN barns connected with MMM bidirectional paths between some pairs o

HDU4496 D-City【并查集】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4496 题目大意: 给出一张图,按照给定的边的顺序逐个删除.问每删除一条边后图的连通块数是多少. 思路: 逆向并查集求联通块数.假设一开始的时候所有点都不连通.从给定边逆着的顺序,即从最后 一条边开始添加.如果新添加的边连通了两个连通分量,则连通块数就减一,否则不改变.将 每次加边后的连通块数存起来.最后输出出来. AC代码: #include<iostream> #include<algo

HDU4496 D-City并查集逆向推理

D-City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 3035    Accepted Submission(s): 1074 Problem Description Luxer is a really bad guy. He destroys everything he met. One day Luxer went to D

P3144 关闭农场 并查集 反向

FJ和他的奶牛们正在计划离开小镇做一次长的旅行,同时FJ想临时地关掉他的农场以节省一些金钱. 这个农场一共有被用M条双向道路连接的N个谷仓(1<=N,M<=3000).为了关闭整个农场,FJ 计划每一次关闭掉一个谷仓.当一个谷仓被关闭了,所有的连接到这个谷仓的道路都会被关闭,而且再也不能够被使用. FJ现在正感兴趣于知道在每一个时间(这里的“时间”指在每一次关闭谷仓之前的时间)时他的农场是否是“全连通的”——也就是说从任意的一个开着的谷仓开始,能够到达另外的一个谷仓.注意自从某一个时间之后,可

L2-013. 红色警报 (并查集)

战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报. 输入格式: 输入在第一行给出两个整数N(0 < N <=500)和M(<=5000),分别为城市个数(于是默认城市从0到N-1编号)和连接两城市的通路条数.随后M行,每行给出一条通路所连接的两个城市的编号,其间以1个空格分隔.在城市信息之后给出被攻

hdu-2874 Connections between cities(lca+tarjan+并查集)

题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, s