题目
给你N点M边的完全图,每次按点的编号不断删除点(从1到n)。
问你每次删除后有几个连通图。
题解思路
不妨从结果往前考虑。
最终状态肯定是一个点都没有,0个连通图。
我们从N往前加边加点。然后将可以连接的点并查起来即可。
这样我们只需建小到大的单项边即可。
大到小的时候,小的点被删除了。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
int n , m ;
vector <int> head[200100] ;
int a[200100] ;
int vis[200100] ;
int find(int x )
{
if ( x != a[x] )
return a[x] = find(a[x]) ;
return a[x] ;
}
int uio (int x , int y )
{
int fx = find(x) ;
int fy = find(y) ;
if ( fx != fy )
{
a[fy] = fx ;
return 1 ;
}
return 0 ;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n >> m ;
for (int i = 1 ; i <= m ; i++ )
{
int t1 , t2 ;
cin >> t1 >> t2 ;
if ( t1 > t2 )
swap(t1,t2);
head[t1].push_back(t2) ;
}
for (int i = 1 ; i <= n ; i++ )
a[i] = i ;
int qs = 0 ;
vector <int> ans ;
ans.push_back(0) ;
for (int i = n ; i > 1 ; i-- )
{
qs++;
for (int j = 0 ; j < head[i].size() ; j++ )
{
int sp = head[i][j] ;
qs -= uio(i,sp);
}
ans.push_back(qs);
}
reverse(ans.begin(),ans.end());
for ( auto i : ans )
cout << i << "\n" ;
return 0 ;
}