博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 4496(并查集逆向添边)
阅读量:5336 次
发布时间:2019-06-15

本文共 2376 字,大约阅读时间需要 7 分钟。

D-City

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Total Submission(s): 2933    Accepted Submission(s): 1038

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.
 
 
 
题目大意:n个点(0-(n-1)) m条边,每次删除一条边,然后求每次剩下的连通分量
题解:先将m条边输入,然后反向添边(m-1->0)得到结果
#include 
#include
#include
using namespace std;const int N = 10005;const int M =100005;int father[N];int _find(int x){ if(x==father[x]) return x; return father[x]=_find(father[x]);}struct Edge{ int s,e;}edge[M];int a[M];int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=0;i
0;i--){ ///从最后一条边开始添加 int x = _find(edge[i].s); int y = _find(edge[i].e); if(x!=y){ father[x] = y; a[i-1] = a[i]-1; } else a[i-1]=a[i]; } for(int i=0;i

 

转载于:https://www.cnblogs.com/liyinggang/p/5330409.html

你可能感兴趣的文章
两个字符串对比提升比较性能用 StringComparison.OrdinalIgnoreCase
查看>>
软件开发 CI、CD的简要思维导图,以及常用的软件
查看>>
对链表的简单复习和理解
查看>>
强化学习精要第一二章
查看>>
Gae&reward shaping
查看>>
强化学习第三四章
查看>>
强化学习第六章
查看>>
强化学习第七章
查看>>
关于vs code和markdown
查看>>
dsjxtjc第一次实验
查看>>
某手游智能反外挂产品原理浅析
查看>>
基于设备指纹零感验证系统
查看>>
IaaS、PaaS和SaaS最浅显易懂的解释
查看>>
VMware上安装ubuntu后忘记密码解决办法(密码重置,亲测有效)
查看>>
KETTLE——初见KETTLE
查看>>
KETTLE——(一)资源库
查看>>
KETTLE——(二)数据抽取
查看>>
KETTLE——(三)数据输出
查看>>
KETTLE——(例)简单的字段转换
查看>>
关于Tomcat的浅谈
查看>>