[POJ3352]Road Construction 做题笔记
来源:互联网 发布:期货行情数据接口 编辑:程序博客网 时间:2024/06/07 22:09
题目来源:http://poj.org/problem?id=3352
引用一下解题思路:http://blog.csdn.net/geniusluzh/article/details/6619575
这道题的意思是说,给你一个无向图,然后问你至少需要添加几条边,可以使整个图变成边双连通分量,也就是说任意两点至少有两条路可以互相连通。我们这样考虑这个问题,属于同一个边双连通分量的任意点是至少有两条通路是可以互相可达的,因此我们可以将一个边双连通分量缩成一个点。然后考虑不在边双连通分量中的点,通过缩点后形成的是一棵树。对于一个树型的无向图,需要添加(度为1的点的个数+1)/2条边使得图成为双连通的。这样问题就是变成缩点之后,求图中度为1的点的个数了。
图是无向图,跑Tarjan的时候把无向图当成有向图跑就行了(就是不走回头路)
做缩点的题的时候一个比较容易犯的马虎错是把原图的点和新图的点混淆,所以类似degree[bel[ver[i]]]写成degree[ver[i]]的问题一定要注意。
另外写邻接表时有时会把当前结点和子节点混淆(就是把ver[i]写成了now),这也要注意。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N=2000,M=2000;int dfn[N],low[N],t=0;int head[N],nxt[M<<1],ver[M<<1],tot=1;bool danger[M<<1];int degree[N],bel[N],scc=0,leaf=0;int n,m;int col[N];void add (int u,int v) { ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;}void Tarjan (int x,int fa) { dfn[x]=low[x]=++t;col[x]=-1; for (int i=head[x];i;i=nxt[i]) { if (ver[i]==fa) continue; if (!dfn[ver[i]]) { Tarjan(ver[i],x); low[x]=min(low[x],low[ver[i]]); if (dfn[x]<low[ver[i]]) danger[i]=danger[i^1]=1;//not node } else if (col[ver[i]]==-1) low[x]=min(low[x],dfn[ver[i]]); } col[x]=1;}void dfs (int x) { bel[x]=scc; for (int i=head[x];i;i=nxt[i]) if (!bel[ver[i]]&&!danger[i]) dfs(ver[i]);//bel[ver[i]] instead of bel[x],this is important}int solve () { for (int i=1;i<=n;i++) { if (bel[i]) continue; ++scc;dfs(i); } for (int u=1;u<=n;u++) { for (int i=head[u];i;i=nxt[i]) if (bel[u]!=bel[ver[i]]) ++degree[bel[ver[i]]]; } for (int i=1;i<=scc;i++) { if (degree[i]==1) ++leaf; } return ((leaf+1)>>1);}int main () { int u,v; while (scanf("%d %d",&n,&m)!=EOF) { memset(head,0,sizeof(head)); memset(degree,0,sizeof(degree)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(danger,0,sizeof(danger)); memset(bel,0,sizeof(bel)); memset(col,0,sizeof(col)); t=0,tot=1,scc=0,leaf=0; for (int i=1;i<=m;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i,0); printf("%d\n",solve()); } return 0;}
0 0
- [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
- poj3352 Road Construction (双连通)
- poj3352 Road Construction 缩点
- POJ3352-Road Construction(边连通分量)
- poj3177 Redundant Paths && poj3352 Road Construction
- POJ3352 Road Construction (双连通分量)
- poj3352 Road Construction(边双连通分量)
- poj3352 Road Construction(加最少边使图双联通)
- 【POJ3352】Road Construction tarjan求边-双连通分量,裸题模板题
- [leetcode] 208. Implement Trie (Prefix Tree) 解题报告
- js正则表达式
- C++ Primer 5th - 1.5 类
- android自定义大括弧
- MXnet: RuntimeError: module compiled against API version a but this version of numpy is 9
- [POJ3352]Road Construction 做题笔记
- OSI七层模型详解
- 利用牛顿法接非线性方程组的Matlab程序实例
- 当数据不够一屏时 实现collectionView的滑动
- matlab随机数
- SQL-select
- [疯狂Java]UDP:接收发送数据报、获取接收到的数据报的相关信息
- 目标跟踪 最简单的目标跟踪(模版匹配)
- linux 下硬链接和软连接