HDoj 4496 D-City(并查集)

71 阅读1分钟

D-City

**Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2523    Accepted Submission(s): 883
**
\

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


考并查集的建法。。
从前向后减=从后向前建


  
  
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int init[10010],ans[100010];int l1[100010],l2[100010];
int fi(int r)
{
    return r==init[r]?r:init[r]=fi(init[r]);
}
void mer(int a,int b)
{
//    int x=fi(a);
//    int y=fi(b);
    if(a>b)
        init[a]=b;
    else
        init[b]=a;
}
int main()
{
    int n,m,i,j,k,a,b;
    ios::sync_with_stdio(false);
    while(cin>>n>>m)
    {
        for(i=0;i<n;i++)
        init[i]=i;
        for(i=0;i<m;i++)
        {
            cin>>a>>b;
            l1[i]=a;//分别保存与数组中
            l2[i]=b;
        }
        ans[m]=n;//减到一条路没有必然是剩下n个城市 
        for(i=m-1;i>=0;i--)
        {
            if(fi(l1[i])!=fi(l2[i]))
            {
                mer(fi(l1[i]),fi(l2[i]));<span id="transmark"></span>
                ans[i]=ans[i+1]-1;
            }
            else
                ans[i]=ans[i+1];
        }
        for(i=1;i<=m;i++)
        {
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}