倒着用并查集维护即可。
#include <bits/stdc++.h>
using namespace std;
const int N= 2e5 + 5 ;
int n, m, k, x, y, xx, yy, total;
int f[ N<< 1 ] , u[ N] , v[ N] , a[ N] , broken[ N<< 1 ] , ans[ N<< 1 ] ;
int cnt, head[ N<< 1 ] ;
struct egde{ int next, to; } e[ N<< 1 ] ;
int find ( int x)
{
if ( f[ x] == x) return x;
return f[ x] = find ( f[ x] ) ;
}
inline void add ( int u, int v)
{
cnt++ ;
e[ cnt] . next= head[ u] ;
e[ cnt] . to= v;
head[ u] = cnt;
}
int main ( ) {
scanf ( "%d%d" , & n, & m) ;
for ( register int i= 1 ; i<= n; ++ i) f[ i] = i;
for ( register int i= 1 ; i<= m; ++ i) scanf ( "%d%d" , & u[ i] , & v[ i] ) , u[ i] ++ , v[ i] ++ ;
scanf ( "%d" , & k) ;
for ( register int i= 1 ; i<= k; ++ i) scanf ( "%d" , & a[ i] ) , a[ i] ++ , broken[ a[ i] ] = 1 ;
for ( register int i= 1 ; i<= m; ++ i)
if ( ! broken[ u[ i] ] && ! broken[ v[ i] ] )
{
x= u[ i] ; y= v[ i] ;
xx= find ( x) ; yy= find ( y) ;
f[ xx] = yy;
}
for ( register int i= 1 ; i<= n; ++ i) if ( ! broken[ i] && find ( i) == i) total++ ;
ans[ k] = total;
for ( register int i= 1 ; i<= m; ++ i)
{
add ( u[ i] , v[ i] ) ;
add ( v[ i] , u[ i] ) ;
}
for ( register int i= k- 1 ; i>= 0 ; -- i)
{
broken[ a[ i+ 1 ] ] = 0 ;
for ( register int j= head[ a[ i+ 1 ] ] ; j; j= e[ j] . next)
{
x= a[ i+ 1 ] ; y= e[ j] . to;
xx= find ( x) ; yy= find ( y) ;
if ( ! broken[ x] && ! broken[ y] && xx!= yy)
{
f[ xx] = yy;
total-- ;
}
}
total++ ;
ans[ i] = total;
}
for ( register int i= 0 ; i<= k; ++ i) printf ( "%d\n" , ans[ i] ) ;
return 0 ;
}