POJ 3177 Redundant Paths <边双连通分量>

来源:互联网 发布:如何组建办公网络 编辑:程序博客网 时间:2024/06/06 10:03

题目:传送门

分析:将图中所有块(双连通分支)缩点过后,再找出所有叶子节点,在它们之间加边就好了。这道题是会有重边的,但是用邻接矩阵存储图G,自动就滤掉重边了。

代码

#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int MAXV=5010;int low[MAXV];int dfn[MAXV];int degree[MAXV];int n,m;bool map[MAXV][MAXV];int time;void initia(){    memset(dfn,0,sizeof dfn);    memset(low,0,sizeof low);    memset(map,false,sizeof map);    memset(degree,0,sizeof degree);    time=0;}void input(){    int a,b;    while(m--){        cin>>a>>b;        map[a][b]=true;        map[b][a]=true;    }}void tarjan(int u,int fa){    low[u]=dfn[u]=++time;    for(int i=1;i<=n;++i){        if(i==fa) continue;        if(map[u][i]){            if(!dfn[i]){                tarjan(i,u);                low[u]=min(low[u],low[i]);            }            else low[u]=min(low[u],dfn[i]);        }    }}void solve(){    tarjan(1,1);    int c=0;    for(int i=1;i<=n;++i){        for(int j=1;j<=n;++j){            if(!map[i][j]) continue;            if(low[j]!=low[i]){                degree[low[i]]++;            }        }    }    for(int i=1;i<=n;++i){        if(degree[i]==1) c++;    }    cout<<(c+1)/2<<endl;}int main(){    ios::sync_with_stdio(false);    int a,b;    while(cin>>n>>m){        initia();        input();        solve();    }    return 0;}
原创粉丝点击