poj 3352 3177 桥 缩点

题意:求至少添加几条边,使原图中没有桥。

分析:找出边连通分量,缩点,形成一棵树,树叶有cnt个,则结果为(cnt+1)/2

 

 

#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;//

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

void dfs(int u, int father) {
    tim[u] = low[u] = t ++;
    sta[++top] = u;
    for(int i = old[u] ; i != -1 ; i = edge[i].next) {
        int v = edge[i].v;
        if(v == father) continue;
        if(tim[v] == -1) {//父子边
            dfs(v, u);
            checkmin(low[u],low[v]);
            if(tim[u] < low[v]){    //i是桥
                bs[bb]=u;
                be[bb++]=v;
            }
        } else checkmin(low[u],tim[v]);//返祖边
    }
    if(tim[u] == low[u]) {           //u是连通分量的第一个点
        int v=-1;
        while(u != v){
            v = sta[top--];
            hash[v]=nb;
        }
        nb++;
    }
}

int cnt;
void Tarjan() {
    FOR(i,1,n+1) {
        if(tim[i] == -1)
            dfs(i , -1);
    }

    memset(rudu,0,sizeof(int)*(nb+1));
    /*FOR(u,1,n+1) {
        for(int i = old[u] ; i != -1 ; i = edge[i].next) {
            int v = edge[i].v;
            if(hash[u] != hash[v])
                rudu[ hash[v] ]++;
        }
    }*/

    FF(i,bb){
        int u=bs[i],v=be[i];
        rudu[ hash[u] ]++;
        rudu[ hash[v] ]++;
    }

    FF(i,nb)
        if(rudu[i]==1)
            cnt++;
    cout<<(cnt+1)/2<<endl;


    /*
    FOR(u,1,n+1) {
        for(int i = old[u] ; i != -1 ; i = edge[i].next) {
            int v = edge[i].v;
            if(low[u] != low[v])
                rudu[ low[v] ]++;
        }
    }
    */
}

void init(){
    memset(old,-1,sizeof(int)*(n+1));
    memset(tim,-1,sizeof(int)*(n+1));
    memset(hash,-1,sizeof(int)*(n+1));
    len = t = top = nb = cnt = bb = 0;
}
void build(){
    int r,a,b;
    cin>>r;
    FF(i,r){
        cin>>a>>b;
        add(old[a],b);
        add(old[b],a);
    }
}

int main(){
    while(cin>>n){
        init();
        build();
        Tarjan();
    }
}

 

#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;//

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

void dfs(int u, int father) {
    tim[u] = low[u] = t ++;
    sta[++top] = u;
    for(int i = old[u] ; i != -1 ; i = edge[i].next) {
        int v = edge[i].v;
        if(v == father) continue;
        if(tim[v] == -1) {//父子边
            dfs(v, u);
            checkmin(low[u],low[v]);
            if(tim[u] < low[v]){    //i是桥
                bs[bb]=u;
                be[bb++]=v;
            }
        } else checkmin(low[u],tim[v]);//返祖边
    }
    if(tim[u] == low[u]) {           //u是连通分量的第一个点
        int v=-1;
        while(u != v){
            v = sta[top--];
            hash[v]=nb;
        }
        nb++;
    }
}

int cnt;
void Tarjan() {
    FOR(i,1,n+1) {
        if(tim[i] == -1)
            dfs(i , -1);
    }

    memset(rudu,0,sizeof(int)*(nb+1));
    /*FOR(u,1,n+1) {
        for(int i = old[u] ; i != -1 ; i = edge[i].next) {
            int v = edge[i].v;
            if(hash[u] != hash[v])
                rudu[ hash[v] ]++;
        }
    }*/

    FF(i,bb){
        int u=bs[i],v=be[i];
        rudu[ hash[u] ]++;
        rudu[ hash[v] ]++;
    }

    FF(i,nb)
        if(rudu[i]==1)
            cnt++;
    cout<<(cnt+1)/2<<endl;


    /*
    FOR(u,1,n+1) {
        for(int i = old[u] ; i != -1 ; i = edge[i].next) {
            int v = edge[i].v;
            if(low[u] != low[v])
                rudu[ low[v] ]++;
        }
    }
    */
}

void init(){
    memset(old,-1,sizeof(int)*(n+1));
    memset(tim,-1,sizeof(int)*(n+1));
    memset(hash,-1,sizeof(int)*(n+1));
    len = t = top = nb = cnt = bb = 0;
}
void build(){
    int r,a,b;
    cin>>r;
    FF(i,r){
        cin>>a>>b;
        add(old[a],b);
        add(old[b],a);
    }
}

int main(){
    while(cin>>n){
        init();
        build();
        Tarjan();
    }
}
3177

 

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