poj 3353 Road Construction tarjan 边双联通分支 缩点+结论
2013-08-12 02:23
423 查看
题意:一个连通的无向图,求至少需要添加几条边,救能保证删除任意一条边,图仍然是连通的。
链接:http://poj.org/problem?id=3352
思路:边的双连通图。其实就是要求至少添加几条边,可以使整个图成为一个边双连通图。用tarjan算法(求割点割边)求出low数组,这里可以简化,然 后依据“low相同的点在一个边连通分量中”,缩点之后构造成树(这里可以直接利用low[]数组,low[i]即为第i节点所在的连通分量的标号)。求 出树中出度为1的节点数left,答案即为(leaf+1)/2。
代码:
View Code
链接:http://poj.org/problem?id=3352
思路:边的双连通图。其实就是要求至少添加几条边,可以使整个图成为一个边双连通图。用tarjan算法(求割点割边)求出low数组,这里可以简化,然 后依据“low相同的点在一个边连通分量中”,缩点之后构造成树(这里可以直接利用low[]数组,low[i]即为第i节点所在的连通分量的标号)。求 出树中出度为1的节点数left,答案即为(leaf+1)/2。
代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stdlib.h> #include <vector> #include <queue> #include <stack> #define loop(s,i,n) for(i = s;i < n;i++) #define cl(a,b) memset(a,b,sizeof(a)) const int maxn = 1005; using namespace std; int dfn[maxn],low[maxn],belong[maxn],dfsclock,bcc_cnt; vector<int>g[maxn]; vector<int>ng[maxn]; struct edge { int u,v,w; }; stack<edge> st; vector<edge> edges; stack<int>s; void init(int n) { int i; for(i = 0; i <= n; i++) g[i].clear(); edges.clear(); return ; } int in[maxn]; void tarjan(int u,int pre) { int v,i,j; dfn[u] = low[u] = ++dfsclock; s.push(u); loop(0,i,g[u].size()) { v = g[u][i]; if(v != pre) { if(!dfn[v])//保证是树枝边 { tarjan(v,u); low[u] = min(low[v],low[u]); } else if(dfn[v] < low[u]) low[u] = dfn[v]; } } if(low[u] ==dfn[u]) { bcc_cnt++; int t; do { t = s.top(); s.pop(); belong[t] = bcc_cnt; } while(t != u); } } void find_bcc(int n) { int i; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(belong,0,sizeof(belong)); while(!s.empty())s.pop(); dfsclock = bcc_cnt = 0; loop(1,i,n) if(!dfn[i]) tarjan(i,-1); // puts("yes"); // printf("%d """"""\n",bcc_cnt); } int main() { int m,n; while(~scanf("%d %d",&n,&m)) { init(n); int i,j; for(i = 1; i <= m; i++) { int u,v; struct edge e; scanf("%d %d",&u,&v); g[u].push_back(v); g[v].push_back(u); e.u = u; e.v = v; edges.push_back(e); } find_bcc(n); cl(in,0); struct edge e; for(j = 0; j < edges.size(); j++) { e = edges[j]; if(belong[e.v] != belong[e.u]) { in[belong[e.v]]++; in[belong[e.u]]++; } } int leaf; leaf = 0; // cout<<bcc_cnt<<endl; for(i = 1; i <= bcc_cnt; i++) if(in[i]==1) leaf++; cout<<(leaf+1)/2<<endl; } return 0; }
View Code
相关文章推荐
- POJ 3352|Road Construction|边双联通分量|Tarjan
- POJ3352 Road Construction【边双联通分量】【Tarjan】
- POJ 3352 Road Construction (边双连通分量 Tarjan缩点)
- POJ 3352 Road Construction POJ 3177Redundant Paths(Tarjan缩点)
- POJ-3352 Road Construction,tarjan缩点求边双连通!
- POJ 3352 Road Construction POJ 3177 Redundant Paths(边双连通图 Tarjan+缩点)
- POJ 3352--Road Construction【无向图增加最少的边成为边双连通图 && tarjan求ebc && 缩点构造缩点树】
- POJ 3352 Road Construction&& POJ 3177 Redundant Paths 双联通分量
- Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告
- poj 3352 Road Construction 缩点
- Road Construction+求双联通分量、割点、桥+POJ
- 【POJ 3352】 Road Construction(边联通分量入门)
- POJ 3177 / POJ 3352 : Redundant Paths / Road Construction - 边双连通分量,缩点
- POJ 3352 Road Construction(边双连通分量,桥,tarjan)
- POJ 3352 Road Construction 边的双连通分量 + 缩点
- poj 3352 Road Construction (tarjan)
- POJ 2186 -- Popular Cows【强连通分支 && Tarjan缩点】
- Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)
- POJ 3352 Road Construction 边双联通分量
- POJ 3352 Road Construction (边双连通,缩点)