NC7501D Router Mesh (去掉割点算连通快的变化)

题意:

给出一个图,按序输出去掉第i个点,剩下的连通快数量。

题解:

割点魔改。

#include<cstdio>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
const int maxn=3e5+100;
vector<int> g[maxn];
int N,M,x,y; 
int low[maxn];
int dfn[maxn];
int cnt;
int scc;
int pos[maxn];
int isGedian[maxn];
int isRoot[maxn];
int cut[maxn];
stack<int> st;
void init () {
    fill (low,low+maxn,0);
    fill (dfn,dfn+maxn,0);
    fill (pos,pos+maxn,0);
    fill (isGedian,isGedian+maxn,0);
    fill (cut,cut+maxn,0);
    for (int i=0;i<maxn;i++) g[i].clear();
    while (!st.empty()) st.pop();
    cnt=0;
    scc=0;
}
void tarjan (int x,int pre) {
    low[x]=dfn[x]=++cnt;
    int son=0;
    st.push(x);
    for (int i=0;i<g[x].size();i++) {
        if (g[x][i]==pre) continue;
        if (!dfn[g[x][i]]) {
            son++;
            tarjan(g[x][i],x);
            low[x]=min(low[x],low[g[x][i]]);
            if ((low[g[x][i]]>=dfn[x]&&x!=pre)||(son>1&&x==pre)) cut[x]++;
        }
        else if (dfn[g[x][i]]<dfn[x]&&g[x][i]!=pre) low[x]=min(low[x],dfn[g[x][i]]);
    }
    
}
int father[maxn];
int size[maxn];
int findfather (int x) {
    int a=x;
    while (x!=father[x]) {
        x=father[x];
    }
    while (a!=father[a]) {
        int z=a;
        a=father[a];
        father[z]=x;
    }
    return x;
}
void Union (int x,int y) {
    x=findfather(x);
    y=findfather(y);
    father[x]=y;
    size[y]+=size[x];
} 
int main () {
    while (~scanf("%d%d",&N,&M)) {
        init ();
        for (int i=1;i<=N;i++) size[i]=1,father[i]=i;
        for (int i=1;i<=M;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
            Union(x,y);
        }
        int sum=0;
        for (int i=1;i<=N;i++) 
        if (!low[i]) tarjan(i,i),sum++;
        for (int i=1;i<=N;i++) {
            //printf("%d %d\n",findfather(i),size[i]);
            if (findfather(i)==i&&size[i]==1) {
                printf("%d ",sum-1);
            }
            else
                printf("%d ",sum+cut[i]);
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2020-10-25 18:13  zlc0405  阅读(92)  评论(0编辑  收藏  举报