首页 > 其他 > 详细

BZOJ 1015 [星球大战 starwar]

时间:2020-01-14 09:47:41      阅读:81      评论:0      收藏:0      [点我收藏+]

题面

题意

??给定无向图,每次删去一个点并求连通分量个数。

题解

??很难在删除点的同时维护联通分量个数,但是如果把操作倒序,问题就变成了每次往无向图里添加一个点并求连通分量个数。可以用并查集维护。


代码

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=4e5+5;
vector<int> e[maxn];
int fa[maxn];
bool vis[maxn];
int arr[maxn],ans[maxn];
int ff(int u){ return fa[u]==u?u:fa[u]=ff(fa[u]); }
int main(){
    int i,j,n,m;
    int u,v;
    int cnt;
    scanf("%d%d",&n,&m);
    while (m--){
        scanf("%d%d",&u,&v);
        e[u].push_back(v); e[v].push_back(u);
    }
    scanf("%d",&m);
    for (i=0;i<n;i++){ fa[i]=i; vis[i]=true; }
    for (i=0;i<m;i++){
        scanf("%d",&arr[i]); vis[arr[i]]=false;
    }
    cnt=n-m;
    for (i=0;i<n;i++) if (vis[i]){
        for (j=0;j<e[i].size();j++){
            u=i; v=e[i][j];
            if (!vis[v]) continue;
            u=ff(u); v=ff(v);
            if (u!=v){ cnt--; fa[u]=v; }
        }
    }
    ans[m]=cnt;
    for (i=m-1;i>=0;i--){
        vis[arr[i]]=true; cnt++;
        for (j=0;j<e[arr[i]].size();j++){
            u=arr[i]; v=e[arr[i]][j];
            if (!vis[v]) continue;
            u=ff(u); v=ff(v);
            if (u!=v){ cnt--; fa[u]=v; }
        }
        ans[i]=cnt;
    }
    for (i=0;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}

BZOJ 1015 [星球大战 starwar]

原文:https://www.cnblogs.com/Kilo-5723/p/12190175.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!