[POJ3177]Redundant Paths 边双连通分量 做题笔记
2016-03-08 23:06
453 查看
题目来源:http://poj.org/problem?id=3177
解题思路:/article/6913509.html
分析:在同一个边双连通分量中,任意两点都有至少两条独立路可达,所以同一个边双连通分量里的所有点可以看做同一个点。
缩点后,新图是一棵树,树的边就是原无向图的桥。
现在问题转化为:在树中至少添加多少条边能使图变为双连通图。
结论:添加边数=(树中度为1的节点数+1)/2
具体方法为,首先把两个最近公共祖先最远的两个叶节点之间连接一条边,这样可以把这两个点到祖先的路径上所有点收缩到一起,因为一个形成的环一定是双连通的。然后再找两个最近公共祖先最远的两个叶节点,这样一对一对找完,恰好是(leaf+1)/2次,把所有点收缩到了一起。
其实求边双连通分量和求强连通分量差不多,每次访问点的时候将其入栈,当low[u]==dfn[u]时就说明找到了一个连通的块,则栈内的所有点都属于同一个边双连通分量,因为无向图要见反向边,所以在求边双连通分量的时候,遇到反向边跳过就行了。
不过貌似这位博主的代码有点。。问题
解题思路:/article/6913509.html
分析:在同一个边双连通分量中,任意两点都有至少两条独立路可达,所以同一个边双连通分量里的所有点可以看做同一个点。
缩点后,新图是一棵树,树的边就是原无向图的桥。
现在问题转化为:在树中至少添加多少条边能使图变为双连通图。
结论:添加边数=(树中度为1的节点数+1)/2
具体方法为,首先把两个最近公共祖先最远的两个叶节点之间连接一条边,这样可以把这两个点到祖先的路径上所有点收缩到一起,因为一个形成的环一定是双连通的。然后再找两个最近公共祖先最远的两个叶节点,这样一对一对找完,恰好是(leaf+1)/2次,把所有点收缩到了一起。
其实求边双连通分量和求强连通分量差不多,每次访问点的时候将其入栈,当low[u]==dfn[u]时就说明找到了一个连通的块,则栈内的所有点都属于同一个边双连通分量,因为无向图要见反向边,所以在求边双连通分量的时候,遇到反向边跳过就行了。
不过貌似这位博主的代码有点。。问题
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N=5005,M=10005; int head ,ver[M<<1],e[M<<1],next[M<<1]; int dfn ,low ,bel ,q[N<<1],ind ,fa ; bool inq ; int tot=1,cnt=0,top=0,scc=0,n,m; void add (int u,int v) { ver[++tot]=v;next[tot]=head[u];head[u]=tot; ver[++tot]=u;next[tot]=head[v];head[v]=tot; } void Tarjan (int x) { low[x]=dfn[x]=++cnt; q[++top]=x;inq[x]=1; int v; for (int i=head[x];i;i=next[i]) { fa[ver[i]]=x; if (!dfn[v=ver[i]]) Tarjan(v),low[x]=min(low[x],low[v]); else if (inq[v] && fa[x]!=v) low[x]=min(low[x],dfn[v]); } int now=0; if (dfn[x]==low[x]) { scc++; while (top&&x!=now) { now=q[top--]; bel[now]=scc; inq[now]=0; } } } int main () { int u,v,w; scanf("%d%d",&n,&m); for (int i=0;i<m;i++) { scanf("%d%d",&u,&v); add(u,v); } for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(1); for (int i=1;i<=n;i++) for (int j=head[i];j;j=next[j]) if (bel[i]!=bel[ver[j]]) ind[bel[i]]++; int sum=0; for (int i=1;i<=n;i++) // if (ind[i]==1) sum++; int ans=(sum+1)/2; printf("%d\n",ans); return 0; }
相关文章推荐
- 在ipython notebook中使用argparse
- Java中的ExceptionInInitializerError 异常解决方法
- HDU 4085 Peach Blossom Spring(斯坦纳树+dp)
- 使它读入被include语句修饰的一个文件并且输出这个文件
- linux下打包,压缩,解压缩
- compass初探
- LeetCode93—Restore IP Addresses
- Django入门(二) 添加外部网页样式
- Python基础(三)之List类型
- OpenJudge百炼习题解答(C++)--题2690:首字母大写
- [PHP]利用XAMPP搭建本地服务器, 然后利用iOS客户端上传数据到本地服务器中(一.安装XAMPP)
- C# 必看书籍
- iOS 开发者必不可少的 75 个工具
- 清除dede漏洞,为金融平台等网站安全护航
- 【BZOJ3339】Rmq Problem【离线】【线段树】【mex】
- java中字符串倒序加逗号输出
- Python基础--快速改造:字符串
- Spring JDBC
- 寻找下一个较大元素
- uva10558