杭电OJ4496 并查集 D-City

来源:互联网 发布:英雄无敌 for mac 编辑:程序博客网 时间:2024/04/29 05:53


D-City

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2849    Accepted Submission(s): 1005


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.


本题解题关键在于输出后边的hint提示

题意大概是这样的:

一个叫做***的人破坏道路 原本n个点是有m条路来连接的.输入顺序为破坏顺序 例如前四个例子

0 1 1 2 1 3


当破坏了这三条边之后和1连接的点就只剩下1 4这条路了 当这条路被破坏的同时  这个点就相当于没有了 这个时候输出就不再是1 而是2了

所以这个题正常思维是破坏道路,但是这个时候读者问我了 你怎么指导在破坏了0 1 1 2 1 3这三条边之后还剩下而且就剩下了1 4这条路没有破坏了呢?(虽然确实是1只能连接0 1 3 4  当破坏了 0 1 3 的时候就只剩下了 1 4这条路)我们是通过输入看出来的~并不是推理出来的(这点一定要铭记)

我们通过输入看出来的 破坏了0  1  1 2 1 3这三条边之后还有1 4 这条边还没有破坏 同理之后的样例也是一样.

所以我们得出了结论 如果倒序连接点 每多连接一个点就改变一次输出的值就行了~

这里贴上AC代码

#include<stdio.h>#include<string.h>using namespace std;struct line{    int x,y;}a[100005];int output[100050];int f[100050];int find(int x){    return f[x] == x ? x : (f[x] = find(f[x]));}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        for(int i=0;i<n;i++)        {            f[i]=i;        }        for(int i=0;i<m;i++)        {            scanf("%d%d",&a[i].x,&a[i].y);        }        output[m-1]=n;        for(int i=m-1;i>0;i--)        {            int b=find(a[i].x);            int c=find(a[i].y);            if(b!=c)            {                f[b]=c;                output[i-1]=output[i]-1;            }            else            {                output[i-1]=output[i];            }        }        for(int i=0;i<m;i++)        printf("%d\n",output[i]);    }}



0 0
原创粉丝点击