Redundant Paths——构造双连通图
Posted j666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redundant Paths——构造双连通图相关的知识,希望对你有一定的参考价值。
题意:
有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走。现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指:没有公共边的路,但可以经过同一个中间顶点。
该图中为连通图
题解:
题意转换一下:
就是给了一个连通图,问加多少条边可以变成边双连通。
我们将原图先缩点, 可以得到一棵树.然后我们统计叶子节点数目leaf(即度为1的点), 最小的加边数即(leaf+1)/2 (成对加边)
考虑重边
代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include<vector> #include <map> using namespace std; const int maxn = 5010;//点数 const int maxm = 20010;//边数,因为是无向图,所以这个值要*2 struct Edge int to,next; bool cut;//是否是桥标记 edge[maxm]; int head[maxn],tot; int low[maxn],dfn[maxn],Stack[maxn],belong[maxn];//belong数组的值是1~scc int Index,top; int scc;//边双连通块数/强连通分量的个数 bool Instack[maxn]; int bridge;//桥的数目 int cut[maxn]; void addedge(int u,int v) edge[tot].to = v; edge[tot].next = head[u]; edge[tot].cut=false; head[u] = tot++; void Tarjan(int u,int pre) int v; low[u] = dfn[u] = ++Index; Stack[top++] = u; Instack[u] = true; int son=0; for(int i = head[u]; i != -1; i = edge[i].next) v = edge[i].to; if(v == pre)continue; if( !dfn[v] ) son++; Tarjan(v,u); if( low[u] > low[v] )low[u] = low[v]; if(low[v] > dfn[u]) bridge++; edge[i].cut = true; edge[i^1].cut = true; if(u == pre && son > 1)cut[u] = true; if(u != pre && low[v] >= dfn[u])cut[u] = true; else if( Instack[v] && low[u] > dfn[v] ) low[u] = dfn[v]; if(low[u] == dfn[u]) scc++; do v = Stack[--top]; Instack[v] = false; belong[v] = scc; while( v!=u ); void init() tot = 0; memset(head,-1,sizeof(head)); int du[maxn]; void solve(int n) memset(dfn,0,sizeof(dfn)); memset(Instack,false,sizeof(Instack)); memset(du,0,sizeof du); memset(cut,0,sizeof cut); Index = top = scc = 0; bridge = 0; for(int i = 1; i <= n; i++) if(!dfn[i]) Tarjan(i,i); for(int i = 1; i <= n; i++) for(int j = head[i]; j != -1; j = edge[j].next) if(edge[j].cut) du[belong[i]]++; int ans=0; for(int i = 1; i <= scc; i++) if(du[i]==1) ans++; //找叶子结点的个数ans,构造边双连通图需要加边(ans+1)/2 printf("%d\\n",(ans+1)/2); int main() int n,m; int u,v; while(scanf("%d%d",&n,&m)==2) init(); while(m--) scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); solve(n); return 0;
以上是关于Redundant Paths——构造双连通图的主要内容,如果未能解决你的问题,请参考以下文章
[POJ3177]Redundant Paths(双连通图,割边,桥,重边)
POJ 3177 Redundant Paths(强连通分量)
POJ 3177--Redundant Paths无向图添加最少的边成为边双连通图 && tarjan求ebc && 缩点构造缩点树(代