首页 > 代码库 > poj 3352Road Construction(无向双连通分量的分解)
poj 3352Road Construction(无向双连通分量的分解)
1 /* 2 题意:给定一个连通的无向图G,至少要添加几条边,才能使其变为强连通图(指的是边强联通)。 3 思路:利用tarjan算法找出所有的双联通分量!然后根据low[]值的不同将双联通分量 4 进行缩点,最后图形会变成一棵树!也就是添加至少多少条边使一棵树变成强联通图! 5
6 知识点:若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么 7 至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2 8 9 */10 #include<iostream>11 #include<cstring>12 #include<cstdio>13 #include<algorithm>14 #include<vector>15 #define N 100516 using namespace std;17 vector<int>g[N]; 18 int low[N], pre[N]; 19 int deg[N];20 int n, m;21 int cnt;22 int dfsClock;23 void dfs(int u, int fa){24 low[u]=pre[u]=++dfsClock;25 int len=g[u].size();26 for(int i=0; i<len; ++i){27 int v=g[u][i];28 if(!pre[v]){29 dfs(v, u);30 low[u]=min(low[u], low[v]);31 }32 else if(pre[v] < pre[u] && fa!=v)33 low[u]=min(pre[v], low[u]);34 }35 }36 37 int main(){38 while(scanf("%d%d", &n, &m)!=EOF){39 memset(pre, 0, sizeof(pre));40 memset(deg, 0, sizeof(deg));41 while(m--){42 int u, v;43 scanf("%d%d", &u, &v);44 g[u].push_back(v);45 g[v].push_back(u);46 }47 cnt=0;48 dfsClock=0;49 dfs(1, -1);50 for(int i=1; i<=n; ++i){51 int len=g[i].size();52 for(int j=0; j<len; ++j){53 int v=g[i][j];54 if(low[i]!=low[v])55 ++deg[low[i]];56 }57 }58 for(int i=1; i<=n; ++i)59 if(deg[i]==1)60 ++cnt;61 printf("%d\n", (cnt+1)/2);62 for(int i=1; i<=n; ++i)63 g[i].clear();64 }65 return 0;66 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。