poj3177 Redundant Paths && poj3352 Road Construction
来源:互联网 发布:c语言求水仙花数的算法 编辑:程序博客网 时间:2024/06/06 22:27
无向连通图最少补充多少条边可以变成边双连通图(不计入重边)
不含重边时:与求有向图的前连通分量类似
1.求无向图的边双连通分量(edge_bcc)
法一:仿照强连通分量(scc)求法。判断条件:pre[u]==low[u]时:u及其子树属于同一边连通分量(正确性未知)
法二:判断条件:存在子节点v,pre[u]<low[v],则u->v为割边(桥),标记桥。再次dfs不经过桥,求得edge_bcc (过繁,舍去)
法三:判断条件:low[u]==low[v],则u和v在一个edge_bcc中。计入bccno[low[u]],但是这种记录下标不一定连续,遍历时需要从1->n,而不是1->edge_bcc_cnt (一般使用该法)
2.edge_bcc缩点后成为森林,题目要求连通图,因此是一棵树。最少增加(度为1的节点+1)/2条边可以成为边连通图
结论:一棵树有k个度为1的点,则至少增加(k+1)/2条边,变成edge_bcc
法一代码:
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<vector>#include<stack>#define ll long long#define INF 0x3f3f3f3f#define maxn 5010#define mem(a,b) memset(a,b,sizeof(a))using namespace std;int n,m;bool w[maxn][maxn];int pre[maxn],low[maxn],bccno[maxn],bcc_cnt,dfs_clock;vector<int> g[maxn];stack<int> S;int du[maxn];void build(){ scanf("%d%d",&n,&m); mem(w,0); for(int i=1;i<=n;i++) g[i].clear(); for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); if(!w[a][b]){ g[a].push_back(b),g[b].push_back(a); w[a][b]=w[b][a]=1; } }}void dfs(int u,int fa){ pre[u]=low[u]=++dfs_clock; S.push(u); for(int i=0;i<g[u].size();i++){ int v=g[u][i]; if(!pre[v]){ dfs(v,u); low[u]=min(low[u],low[v]); } else if(v!=fa&&!bccno[v]) low[u]=min(low[u],pre[v]); } if(pre[u]==low[u]){ bcc_cnt++; for(;;){ int x=S.top();S.pop(); bccno[x]=bcc_cnt; if(x==u) break; } }}void find_edgebcc(){//不含重边的无向图求edge_bcc mem(pre,0),mem(bccno,0),dfs_clock=bcc_cnt=0; for(int i=1;i<=n;i++) if(!pre[i]) { dfs(i,-1); }}void cal_bcc_du(){ mem(du,0); for(int u=1;u<=n;u++){ for(int i=0;i<g[u].size();i++){ int v=g[u][i]; if(bccno[u]!=bccno[v]) { du[bccno[u]]++,du[bccno[v]]++; } } }}int main(){ //freopen("a.txt","r",stdin); build(); find_edgebcc(); cal_bcc_du(); int du1_cnt=0; for(int i=1;i<=n;i++){ if(du[i]==2) du1_cnt++; } printf("%d\n",(du1_cnt+1)/2);}
法三代码:
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<vector>#include<stack>#define ll long long#define INF 0x3f3f3f3f#define maxn 5010#define mem(a,b) memset(a,b,sizeof(a))using namespace std;int n,m;bool w[maxn][maxn];int pre[maxn],low[maxn],bccno[maxn],bcc_cnt,dfs_clock;vector<int> g[maxn];stack<int> S;int du[maxn];void build(){ scanf("%d%d",&n,&m); mem(w,0); for(int i=1;i<=n;i++) g[i].clear(); for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); if(!w[a][b]){ g[a].push_back(b),g[b].push_back(a); w[a][b]=w[b][a]=1; } }}void dfs(int u,int fa){ pre[u]=low[u]=++dfs_clock; for(int i=0;i<g[u].size();i++){ int v=g[u][i]; if(!pre[v]){ dfs(v,u); low[u]=min(low[u],low[v]); } else if(v!=fa) low[u]=min(low[u],pre[v]); }}void find_edgebcc(){//不含重边的无向图求edge_bcc mem(pre,0),mem(bccno,0),dfs_clock=bcc_cnt=0; for(int i=1;i<=n;i++) if(!pre[i]) dfs(i,-1);}void cal_bcc_du(){ mem(du,0); for(int u=1;u<=n;u++){ for(int i=0;i<g[u].size();i++){ int v=g[u][i]; if(low[u]!=low[v]) { du[low[u]]++,du[low[v]]++; } } }}int main(){ //freopen("a.txt","r",stdin); build(); find_edgebcc(); cal_bcc_du(); int du1_cnt=0; for(int i=1;i<=n;i++){ if(du[i]==2) du1_cnt++; } printf("%d\n",(du1_cnt+1)/2);}
0 0
- poj3177 Redundant Paths && poj3352 Road Construction
- POJ 3177——Redundant Paths && POJ3352——Road Construction
- poj3352 - Road Construction
- POJ3352--Road Construction
- poj3352 Road Construction
- poj3352 Road Construction
- POJ3352-Road Construction
- POJ3352-Road Construction
- poj3352 Road Construction
- poj3352 Road Construction
- poj3352-Road Construction
- poj3177 - Redundant Paths
- POJ3177--Redundant Paths
- 【POJ3177】Redundant Paths
- poj3177 Redundant Paths
- poj3177 Redundant Paths
- POJ3177 Redundant Paths
- POJ3177 Redundant Paths
- ECLIPSE中部署工程报“Undefined exploded archive location”错误的解决方法。
- HDU2544 最短路【Dijkstra算法】
- JAVA生成图片验证码
- spring的IOC和AOP实现的设计模式
- Mongoose Guide
- poj3177 Redundant Paths && poj3352 Road Construction
- HDOJ1001
- PHP登陆注册页面的设计感悟
- 灰度图与彩图的双边滤波
- 长期更新--零碎的小算法技巧
- Java字符串中常见的一些问题
- 探究java.lang.OutOfMemoryError: PermGen space
- C++标准库---copy()©_backward()
- UFLDL——Exercise: Convolution and Pooling 卷积和池化