poj 1523 割点

题意:问每个割点分别和几个连通分量相连

分析:每确定一次u是割点,rudu[u]+1,若u不是根又是割点,rudu[u]再+1

 

 

#define M 1011
struct Node{
    int v,next;
}edge[M<<4];
int len;
int old[M],n;
int nb;
int tim[M],t;
int sta[M],top;
int low[M],hash[M];//原结点向新结点映射
int rudu[M];
int bs[M],be[M],bb;//

int Case;

void add(int &kind,int v){
    edge[len].next=kind;
    edge[len].v=v;
    kind=len++;
}

int rtIsPoint;//根是否是割点
void dfs(int u, int father) {
    tim[u] = low[u] = t ++;
    sta[++top] = u;
    bool isu=false;              //cout<<"AAAAAAAAAA"<<endl;
    for(int i = old[u] ; i != -1 ; i = edge[i].next) {
        int v = edge[i].v;
        if(v == father) continue;           //cout<<"v="<<v<<endl;
        if(tim[v] == -1) {//父子边
                                          //cout<<u<<' '<<v<<' '<<father<<endl;
            dfs(v, u);
            checkmin(low[u],low[v]);
            if(father == -1 && i == old[u])//判根是否割点
                for(int j = edge[i].next; j!=-1; j=edge[j].next)
                    if(tim[ edge[j].v ] == -1){rtIsPoint = 1; break;}
                                                    //cout<<u<<' '<<v<<' '<<tim[u]<<' '<<low[v]<<endl;
            if((tim[u] <= low[v] && father != -1) ||     //u是割点
                (rtIsPoint == 1 && father == -1)){
                    isu=true;
                    //while(u != sta[top]) hash[ sta[top--] ]=nb;
                    //nb++;
                    //bs[bb]=u;   //割点到相连的分量的一条边
                    //be[bb++]=v;
                    rudu[u]++;
            }
        } else checkmin(low[u],tim[v]);//返祖边
    }
    if(isu && father != -1) rudu[u]++;
}

int cnt;
void Tarjan() {                          //cout<<"BBBBBBB"<<endl;
    FOR(i,1,n+1) {
        rtIsPoint=0;
        if(tim[i] == -1)
            dfs(i , -1);
    }

    cout<<"Network #"<<++Case<<endl;
    FF(i,n+1)
        if(rudu[i]){
            cout<<"  SPF node "<<i<<" leaves "<<rudu[i]<<" subnets"<<endl;
            cnt++;
        }
    if(!cnt)cout<<"  No SPF nodes"<<endl;
    cout<<endl;
}

void init(){                                        //cout<<n<<endl;

    memset(tim,-1,sizeof(int)*(n+1));
    //memset(hash,-1,sizeof(int)*(n+1));
    memset(rudu,0,sizeof(int)*(n+1));               //cout<<tim[5]<<endl;
    len = t = top = nb = cnt = bb = rtIsPoint = 0;
}

void build(){
    int a,b;
    while(cin>>a,a){
        cin>>b;
        add(old[a],b);
        add(old[b],a);
        n++;
    }
}

int main()
{
    int a,b;
    while(cin>>a,a){
        cin>>b;
        memset(old,-1,sizeof(old));
        add(old[a],b);
        add(old[b],a);
        n++;

        build();
        init();
        Tarjan();

    }
}

 

posted @ 2013-06-21 12:48  心向往之  阅读(121)  评论(0编辑  收藏  举报