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;
}