POJ 3177 Redundant Paths (边双连通+缩点)
<题目链接>
<转载于 >>> >
题目大意:
有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走。现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指:没有公共边的路,但可以经过同一个中间顶点。
解题分析:
在同一个边双连通分量中,任意两点都有至少两条独立路可达,所以同一个边双连通分量里的所有点可以看做同一个点。
缩点后,新图是一棵树,树的边就是原无向图的桥。
现在问题转化为:在树中至少添加多少条边能使图变为双连通图。
结论:添加边数=(树中度为1的节点数+1)/2
具体方法为,首先把两个最近公共祖先最远的两个叶节点之间连接一条边,这样可以把这两个点到祖先的路径上所有点收缩到一起,因为一个形成的环一定是双连通的。然后再找两个最近公共祖先最远的两个叶节点,这样一对一对找完,恰好是(leaf+1)/2次,把所有点收缩到了一起。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std;const int N = 5e3+5 , M = 1e4+5; #define clr(a,b) memset(a,b,sizeof(a)) struct Edge{int to,next; }edge[M<<1];int head[N],low[N],dfn[N],belong[N],deg[N],stk[N],instk[N]; int n,m,tot,cnt,top,scc; void addEdge(int u,int v){edge[tot].to=v,edge[tot].next=head[u];head[u]=tot++; } void init(){tot=cnt=top=scc=0;clr(head,-1);clr(low,0);clr(dfn,0);clr(instk,0);clr(deg,0); } void Tarjan(int u,int fa){low[u]=dfn[u]=++cnt;stk[++top]=u;instk[u]=1;for(int i=head[u];~i;i=edge[i].next){int v=edge[i].to;if(i==(fa^1))continue; //不能用搜索树上的边来更新low值,这种写法能够用来处理重边的情况if(!dfn[v]){Tarjan(v,i);low[u]=min(low[u],low[v]);}else if(instk[v]) //此时栈里的所有元素均属于同一边双连通分量,找连通分量的根的时候一定要规定这点,否则可能会与其他连通分量的dfn比较low[u]=min(low[u],dfn[v]); //low值全部等于该双连通分量中最先遍历的点dfn值 }if(dfn[u]==low[u]){++scc; while(true){int v=stk[top--];instk[v]=0;belong[v]=scc; //将该联通块中的所有点全部缩点染色if(v==u)break;} } } int main(){while(scanf("%d%d",&n,&m)!=EOF){init();for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);addEdge(u,v),addEdge(v,u);}Tarjan(1,-1);for(int i=1;i<=n;i++){for(int j=head[i];j!=-1;j=edge[j].next){int v=edge[j].to;if(belong[i]!=belong[v])deg[belong[i]]++; //求出缩点后每个点的度 }}int sum=0;for(int i=1;i<=scc;i++)if(deg[i]==1)sum++; //寻找度为1的叶子节点 int ans=(sum+1)/2; printf("%d\n",ans);} }
2018-11-07
转载于:https://www.cnblogs.com/00isok/p/9919653.html
POJ 3177 Redundant Paths (边双连通+缩点)相关推荐
- POJ - 3177 Redundant Paths(边双缩点)
题目链接:点击查看 题目大意:给出一个由n个点和m条边构成的无向图,现在问至少添加几条边,才能使得任意两点之间都能由至少两条不同的路到达 题目分析:既然要让任意两点之间至少由两条道路连接,换句话说也就 ...
- POJ 3177 Redundant Paths(边双联通分量)
题目描述: In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1 ...
- POJ 3352 Road Construction ; POJ 3177 Redundant Paths (双联通)
这两题好像是一样的,就是3177要去掉重边. 但是为什么要去重边呢??????我认为如果有重边的话,应该也要考虑在内才是. 这两题我用了求割边,在去掉割边,用DFS缩点. 有大神说用Tarjan,不过 ...
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...
- poj 3177 Redundant Paths(tarjan边双连通)
题目链接:http://poj.org/problem?id=3177 题意:求最少加几条边使得没对点都有至少两条路互通. 题解:边双连通顾名思义,可以先求一下连通块显然连通块里的点都是双连通的,然后 ...
- POJ - 3177 Redundant Paths 双联通补边
题目链接 题意:给出一个多条边问需要加几条变才能变成双连通图. 首先要缩点,缩点之后就是变成了一个没有强连通分量的图,这时候只需要统计入度为1的点有多少个,然后通过观察发现将点两两连接即可,answe ...
- poj 3177 Redundant Paths
双连通分量 题意:给一个无向图,问要添加多少条边形成边双连通分量.注意图一开始是连通的,所以只要从一个点开始dfs一次就行了,另外这图有重边,(1,2)(2,1)这样,则1,2就形成了一个边双连通分量 ...
- Tarjan算法 —— 强连通双连通缩点 模板
TP 强连通缩点模板 双连通缩点模板 边双连通 点双连通 有向图 我们知道在一张 有向无环 图(也叫 DAG)中,肯定存在拓扑序.拓扑序的特殊顺序性质,能够允许我们在 O(n+m)O(n + m)O( ...
- Redundant Paths POJ - 3177(tarjan+边双连通分量)
题意: 有n个牧场,要求从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路.两条独立的路是指:没有公共边的路,但可以经过 ...
最新文章
- python和java哪个-Java和Python现在都很热门,哪个更有前途?
- 查看python安装路径-在cmd中查看python的安装路径方法
- linux下错误的捕获:errno、perror和strerror的使用
- unity, Gizmos.DrawMesh一个坑
- javabean和java类_java对象 POJO和JavaBean的区别
- HFSS19 官方中文教程系列 L06
- 软考中级网络工程师全面学习笔记第1版(近4万字)
- 计算机教育课题申请报告,课题结项申请报告
- 产品经理必备技能之业务流程图
- 计算机软件网络工程师考试试题,网络工程师考试试题及答案.doc
- 弹力弹珠java_Java趣味小程序:打弹珠
- 【C语言】从字符串中提取IP地址最简洁的方法
- oracle11g迁移到DM8操作过程
- php基本变量,PHP-语法及变量基本操作
- javaSE探赜索隐之三<类与对象的爱恨情仇上>
- 【Echarts Gallery】简单使用
- 开启产品经理之路-产品模型制作
- word图片另存为变黑色_别处复制过来的 图像在word中粘贴后变黑怎么处理?
- wia twain for java,c – 使用WIA或TWAIN扫描页面
- 群控系统linux脚本,群控脚本if then