【bzoj 1015】[JSOI2008]星球大战starwar

来源:互联网 发布:蛋白质晶体结构数据库 编辑:程序博客网 时间:2024/05/21 07:58

注意:开始的信息可以用邻接链表存虚边,在使用vis数组的时候,要注意要用的值是真是假。

#include <bits/stdc++.h>using namespace std;const int maxn = 400010;struct node{    int x, y;};bool cmp(node a, node b){    if(a.x == b.x) return a.y < b.y;    return a.x < b.x;}node p[maxn];bool b1[maxn];int a1[maxn], fa[maxn], msize[maxn], pos[maxn];int _first[maxn], _next[maxn], _to[maxn];int n, m, k, cnt1, cnt2, cnt3, size;int find(int x){    if(fa[x] == x) return x;    return fa[x] = find(fa[x]);}void add(int a, int b){    _next[++cnt2] = _first[a];    _first[a] = cnt2;    _to[cnt2] = b;}int main(){    scanf("%d%d", &n, &m);    for(int i = 0; i < n; i ++) fa[i] = i;    for(int i = 1; i <= m; i ++){        int a, b;        scanf("%d%d", &a, &b);        add(a,b), add(b,a);    }    scanf("%d", &k);    for(int i = 1; i <= k; i ++){        int a;        scanf("%d", &a);        b1[a] = 1;        a1[++cnt1] = a;    }    // ************先把不攻击的连起来***************     size = n-k;    for(int i = 0;i < n; i ++){        if(b1[i] == 1) continue;        for(int j = _first[i]; j; j = _next[j])            if(!b1[_to[j]])                if(find(i) != find(_to[j]))                    fa[fa[i]] = _to[j], size --;    }    // *************倒着加入***************************     for(int i = cnt1; i >= 1; i --){        msize[++cnt3] = size;                 int now = a1[i];        size ++, b1[now] = 0;        for(int j = _first[now]; j; j = _next[j]){            if(!b1[_to[j]] && find(_to[j]) != find(now))                fa[fa[_to[j]]] = now, size --;        }    }    msize[++cnt3] = size;    for(int i = cnt3; i >= 1; i --){        printf("%d\n", msize[i]);    }    return 0;}


1 0
原创粉丝点击