UVA315 Network

割点的概念:对于无向图,删除这个点与其相连的边,整个图的连通分量个数增加。

对于无向图的tarjan算法,必须要设前驱~

求割点的模板~

#include
#include
#include
#include
#include
using namespace std;
const int maxn=1014;
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];
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);
    for (int i=0;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) {
        if (g[x][i]==pre) continue;
        if (!low[g[x][i]]) {
            son++;
            tarjan(g[x][i],x);
            low[x]=min(low[x],low[g[x][i]]);
            if (x!=pre&&dfn[x]<=low[g[x][i]]) isGedian[x]=1;
        }
        else if (!pos[g[x][i]]) low[x]=min(low[x],dfn[g[x][i]]);
    }
    if (low[x]==dfn[x]) {
        scc++;
        while (1) {
            int u=st.top();
            st.pop();
            low[u]=low[x];
            pos[u]=scc;
            if (u==x) break;
        }
    }
    if (x==pre&&son>1) isGedian[x]=1;
}
int main () {
    while (scanf("%d",&N)&&N) {
        init ();
        while (scanf("%d",&x)&&x) {
            char ch;
            while ((ch=getchar())!='\n') {
                scanf ("%d",&y);
                g[x].push_back(y);
                g[y].push_back(x);
            }
        }
        for (int i=1;i<=N;i++) 
        if (!low[i]) tarjan(i,i);
        int gedian=0;
        for (int i=1;i<=N;i++) 
        if (isGedian[i]) gedian++;
        printf ("%d\n",gedian);
    }
    return 0;
}

 

你可能感兴趣的:(UVA315 Network)