POJ 3177 Redundant Paths && POJ 3352
2017-03-16 12:41
337 查看
POJ 3177 Redundant Paths && POJ 3352
边-双连通分量,图论
传送门:POJ 3177传送门:HustOJ
题意
这两题差不多,都是给你个联通无向图,问你至少添加多少条边才能让图中任意两点间都有两条路(指边不重复的路)。关于双连通分量,请参考离散数学图论。
区别在于,3177,有重边。3352保证输入没有重边。而且3177后台测试数据答案好像认为重边只算一条边。
比如3个点4条边,点1点2之间有两条边,点2点3之间有两条边。这样理论上每两点之间都有两条路,不需要添加边了,输出0。就是代码里面不需要去重边(详见代码),然而没有去重的代码会WA,需要加上去重。相当于12之间有一条边,23之间有一条边,输出1。
思路
其实双连通分量代码跟targan的强连通分量差不多,思想是一样的,加一点修改就好。用targan缩点,把双联通块缩起来。然后对新图统计入度(因为无向联通图,所以所有点入度至少是1),只需要把所有入度1的点连起来就好,需要(sum+1)/2条边。
targan双连通分量:
struct Targan//求边双联通分量 { vector<int> G[MAXN]; int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt; stack<int> S; void Addedge(int u, int v) { //这个for循环是去重编用的 for(int i=0;i<G[u].size();i++) { if(G[u][i]==v) return; } G[u].push_back(v); G[v].push_back(u); } void init() { while(!S.empty()) S.pop(); for(int i=0;i<MAXN;i++) G[i].clear(); } void dfs(int u, int fa)//无向图,防止搜到他爸爸那里,加个fa判断 { pre[u]=lowlink[u]=++dfs_clock; S.push(u); for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(v==fa) continue;//无向图,防止搜到他爸爸那里,加个fa判断 //无向图只有树边和反向边两种,if对应树边,继续下搜,else对应反向边,更新low并且统计双联通块 if(!pre[v]) { dfs(v, u); lowlink[u]=min(lowlink[u], lowlink[v]); } else { lowlink[u]=min(lowlink[u], pre[v]); } } if(lowlink[u]==pre[u]) { scc_cnt++; while(1) { int x=S.top();S.pop(); sccno[x]=scc_cnt; if(x==u) break; } } } void find_scc(int n) { dfs_clock=scc_cnt=0; M(sccno, 0);M(pre, 0);M(lowlink, 0); for(int i=1;i<=n;i++) { if(!pre[i]) dfs(i, -1); } } }targan;
代码
写了一晚上wa在去重边上。。#include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <cmath> #include <queue> #include <stack> #include <map> #define _ ios_base::sync_with_stdio(0),cin.tie(0) #define M(a,b) memset(a,b,sizeof(a)) using namespace std; const int MAXN=10005; const int oo=0x3f3f3f3f; typedef long long LL; const LL loo=4223372036854775807ll; typedef long double LB; const LL mod=1e9+7; struct Targan//求边双联通分量 { vector<int> G[MAXN]; int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt; stack<int> S; void Addedge(int u, int v) { //这个for循环是去重编用的 for(int i=0;i<G[u].size();i++) { if(G[u][i]==v) return; } G[u].push_back(v); G[v].push_back(u); } void init() { while(!S.empty()) S.pop(); for(int i=0;i<MAXN;i++) G[i].clear(); } void dfs(int u, int fa) { pre[u]=lowlink[u]=++dfs_clock; S.push(u); for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(v==fa) continue; if(!pre[v]) { dfs(v, u); lowlink[u]=min(lowlink[u], lowlink[v]); } else { lowlink[u]=min(lowlink[u], pre[v]); } } if(lowlink[u]==pre[u]) { scc_cnt++; while(1) { int x=S.top();S.pop(); sccno[x]=scc_cnt; if(x==u) break; } } } void find_scc(int n) { dfs_clock=scc_cnt=0; M(sccno, 0);M(pre, 0);M(lowlink, 0); for(int i=1;i<=n;i++) { if(!pre[i]) dfs(i, -1); } } }targan; int indegree[MAXN]; int main() { _; int n; while(cin>>n) { int m;cin>>m; targan.init(); M(indegree, 0); while(m--) { int a, b;cin>>a>>b; targan.Addedge(a, b); } targan.find_scc(n); for(int i=1;i<=n;i++) { for(int j=0;j<targan.G[i].size();j++) { int to=targan.G[i][j]; if(targan.sccno[i]!=targan.sccno[to]) { indegree[targan.sccno[to]]++; } } } int sum=0; for(int i=1;i<=targan.scc_cnt;i++) { if(indegree[i]==1) sum++; } cout<<(sum+1)/2<<endl; } return 0; }
相关文章推荐
- POJ 3177——Redundant Paths && POJ3352——Road Construction
- POJ 3177 Redundant Paths & POJ 3352 Road Construction(双连通分量)
- [双连通分量 缩点 并查集] POJ 3177 Redundant Paths & 3352 Road Construction
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连通)
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
- POJ 3177 / POJ 3352 : Redundant Paths / Road Construction - 边双连通分量,缩点
- POJ 3177 Redundant Paths + POJ 3352 Road Construction
- poj 3177 Redundant Paths 边双连通分量
- poj 3177 & 3352 【无向图双连通分量Tarjan】
- poj 3177 Redundant Paths
- POJ-3177-Redundant Paths
- poj&nbsp;3177&nbsp;Redundant&nbsp;Paths&nbsp;(双连…
- poj 3177 Redundant Paths 加入最少的边,使得无向图为一个双连通分支 有重边
- POJ 3177 Redundant Paths / 边双连通分量
- Poj 3352 Road Construction & Poj 3177 Redundant Paths(边双连通分量+缩点)
- POJ 3177 Redundant Paths - from lanshui_Yang
- 【连通图|边双连通+缩点】POJ-3177 Redundant Paths
- poj 3177 Redundant Paths 边双连通分量+缩点
- poj 3177 Redundant Paths tarjan
- [边双连通分量] poj 3177 Redundant Paths