BZOJ1015 星球大戰

題目來源luogu,如果有侵權請聯繫博主刪除
題解:
同樣是一道好題,考查了我們對於逆向思維的理解。從最後開始加點,每次詢問剩下聯通塊的個數,這樣就迎刃而解了。

/*
  ID:Agreement
  LANG:C++
*/
// Invincible
#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )
using namespace std;
inline int _read(){
    register int x = 0 , f = 1;
    register char ch = getchar();
    while( ch > '9' || ch < '0' ) { if( ch == '-' ) f = -1; ch = getchar(); }
    while( ch >= '0' && ch <= '9' ){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
const int maxn = 400000 + 5;
int N , M , d , tot , f[maxn] , head[maxn] , q[maxn] , ans[maxn] , _t = 0;
bool used[maxn] , des[maxn];
struct edge{
    int v , nxt;
}e[maxn];
inline void ins( int u , int v ){
    e[_t].v = v , e[_t].nxt = head[u] , head[u] = _t; _t++;
    e[_t].v = u , e[_t].nxt = head[v] , head[v] = _t; _t++; 
} 
int getfa( int x ){ return x == f[x] ? x : f[x] = getfa(f[x]); }
inline void add( int x ){
    int p = getfa(x) , q , v;
    erep( i , x )
        if( used[e[i].v] ){
            q = getfa( e[i].v );
            if( p != q ) f[q] = p , tot--;
        }
}
int main(){
    memset( head , 0xff , sizeof head );
    int u , v;
    N = _read() , M = _read();
    rep( i , 0 , N - 1 ) f[i] = i;
    rep( i , 1 , M ){
        u = _read() , v = _read();
        ins( u , v );
    } 
    d = _read();
    rep( i , 1 , d ) q[i] = _read() , des[q[i]] = 1;
    rep( i , 0 , N - 1 )
        if( !des[i] ){
            ++tot , add( i ) , used[i] = 1;
        }
    ans[d + 1] = tot;
    per( i , d , 1 ){
        tot++ , add( q[i] ) , used[q[i]] = 1 , ans[i] = tot;
    } 
    rep( i , 1 , d + 1 ) printf("%d\n" , ans[i]);
    return 0;
}
發佈了48 篇原創文章 · 獲贊 3 · 訪問量 4054
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章