POJ3177 Redundant Paths【边双联通分量】【Tarjan】
2015-02-17 21:54
387 查看
题目链接:
http://poj.org/problem?id=3177
题目大意:
Bessie的农场有F块牧场,已知当前任意两个农场之间至少有一条路径相连(并不一定直接相连)
为了从某块牧场移动到另一块牧场,Bessie和她的伙伴经常需要经过腐烂的树林。奶牛们特别
反感经过不好走的路,于是Bessie决定在农场种再建几条路,使得在去某个地方时总能够有两
条完全独立的路可够选择。那么问题来了:F块牧场,R条路,问至少再修几条路就能使得农场
中任意两个牧场之间都有至少两条相互独立的路径。
思路:
为了使农场中任意两个牧场之间都有至少两条相互独立的路径。也就是把F块牧场看做点,R条
路看做是两个农场之间的双向边。那么问题就转换为:最少添加几条边,可以使图不存在割边。
也就是和POJ3352一样的问题:最少添加几条边,使得任意两个边连通分量之间相互双连通。
具体做法参考博文:http://blog.csdn.net/lianai911/article/details/43867789
注:此题比POJ3352多了一点,需要判重。。。所以我用了Map[][]数组。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 5050;
const int MAXM = 50500;
bool Map[MAXN][MAXN];
struct EdgeNode
{
int to;
int next;
}Edges[MAXM];
int Head[MAXN];
int dfn[MAXN],low[MAXN],Stack[MAXN],degree[MAXN];
int m,id,scc,lay,M,N;
void AddEdges(int u,int v)
{
Edges[id].to = v;
Edges[id].next = Head[u];
Head[u] = id++;
}
void TarjanBFS(int pos,int from)
{
//Stack[m++] = pos;
dfn[pos] = low[pos] = ++lay;
for(int i = Head[pos]; i != -1; i = Edges[i].next)
{
if(Edges[i].to == from)
continue;
if( !dfn[Edges[i].to] )
{
TarjanBFS(Edges[i].to,pos);
low[pos] = min(low[pos],low[Edges[i].to]);
// if( dfn[pos] < low[Edges[i].to] )
// {
// while(Stack[m--] != Edges[i].to);
// }
}
else
low[pos] = min(low[pos],low[Edges[i].to]);
}
}
int main()
{
int u,v;
while(~scanf("%d%d",&N,&M))
{
memset(Head,-1,sizeof(Head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(degree,0,sizeof(degree));
m = lay = scc = id = 0;
memset(Map,0,sizeof(Map));
for(int i = 0; i < M; ++i)
{
scanf("%d%d",&u,&v);
if(Map[u][v] == 0)
{
AddEdges(u,v);
AddEdges(v,u);
Map[u][v] = Map[v][u] = 1;
}
}
TarjanBFS(1,-1);
for(int i = 1; i <= N; ++i)
{
for(int j = Head[i]; j != -1; j = Edges[j].next)
{
if(low[i] != low[Edges[j].to])
degree[low[i]]++;
}
}
int ans = 0;
for(int i = 1; i <= N; ++i)
if(degree[i] == 1)
ans++;
printf("%d\n",(ans+1)/2);
}
return 0;
}
http://poj.org/problem?id=3177
题目大意:
Bessie的农场有F块牧场,已知当前任意两个农场之间至少有一条路径相连(并不一定直接相连)
为了从某块牧场移动到另一块牧场,Bessie和她的伙伴经常需要经过腐烂的树林。奶牛们特别
反感经过不好走的路,于是Bessie决定在农场种再建几条路,使得在去某个地方时总能够有两
条完全独立的路可够选择。那么问题来了:F块牧场,R条路,问至少再修几条路就能使得农场
中任意两个牧场之间都有至少两条相互独立的路径。
思路:
为了使农场中任意两个牧场之间都有至少两条相互独立的路径。也就是把F块牧场看做点,R条
路看做是两个农场之间的双向边。那么问题就转换为:最少添加几条边,可以使图不存在割边。
也就是和POJ3352一样的问题:最少添加几条边,使得任意两个边连通分量之间相互双连通。
具体做法参考博文:http://blog.csdn.net/lianai911/article/details/43867789
注:此题比POJ3352多了一点,需要判重。。。所以我用了Map[][]数组。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 5050;
const int MAXM = 50500;
bool Map[MAXN][MAXN];
struct EdgeNode
{
int to;
int next;
}Edges[MAXM];
int Head[MAXN];
int dfn[MAXN],low[MAXN],Stack[MAXN],degree[MAXN];
int m,id,scc,lay,M,N;
void AddEdges(int u,int v)
{
Edges[id].to = v;
Edges[id].next = Head[u];
Head[u] = id++;
}
void TarjanBFS(int pos,int from)
{
//Stack[m++] = pos;
dfn[pos] = low[pos] = ++lay;
for(int i = Head[pos]; i != -1; i = Edges[i].next)
{
if(Edges[i].to == from)
continue;
if( !dfn[Edges[i].to] )
{
TarjanBFS(Edges[i].to,pos);
low[pos] = min(low[pos],low[Edges[i].to]);
// if( dfn[pos] < low[Edges[i].to] )
// {
// while(Stack[m--] != Edges[i].to);
// }
}
else
low[pos] = min(low[pos],low[Edges[i].to]);
}
}
int main()
{
int u,v;
while(~scanf("%d%d",&N,&M))
{
memset(Head,-1,sizeof(Head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(degree,0,sizeof(degree));
m = lay = scc = id = 0;
memset(Map,0,sizeof(Map));
for(int i = 0; i < M; ++i)
{
scanf("%d%d",&u,&v);
if(Map[u][v] == 0)
{
AddEdges(u,v);
AddEdges(v,u);
Map[u][v] = Map[v][u] = 1;
}
}
TarjanBFS(1,-1);
for(int i = 1; i <= N; ++i)
{
for(int j = Head[i]; j != -1; j = Edges[j].next)
{
if(low[i] != low[Edges[j].to])
degree[low[i]]++;
}
}
int ans = 0;
for(int i = 1; i <= N; ++i)
if(degree[i] == 1)
ans++;
printf("%d\n",(ans+1)/2);
}
return 0;
}
相关文章推荐
- POJ3177 Redundant Paths —— 边双联通分量 + 缩点
- POJ3177_Redundant_Paths_边双连通分量_tarjan
- POJ 3177 Redundant Paths 边双联通分量 缩点
- BZOJ 1718 [Usaco2006 Jan] Redundant Paths 分离的路径 双联通分量
- poj3177 - Redundant Paths-tarjan缩点+求度为1的点
- Redundant Paths POJ - 3177 边双联通分量
- poj1236|poj3177 tarjan,强联通,有向/无向
- poj1236&nbsp;强联通分量(tarjan)
- 迷宫城堡 Tarjan求出强联通分量的个数
- BZOJ2140: 稳定婚姻 Tarjan求无向图强联通分量
- UVALive3523 [Knights of the Round Table] tarjan求无向图双联通分量
- tarjan求强联通分量 模板
- BZOJ 2438 杀人游戏 强联通分量tarjan缩点
- Codeforces-949C:Data Center Maintenance(Tarjan强联通分量)
- 【poj3177】【双连通分量】Redundant Paths
- poj-3177-Redundant Paths-tarjan
- HDU 1269 移动城堡 联通分量 Tarjan
- Tarjan 算法求强联通分量
- [ACM] HDU 1269 迷宫城堡(Tarjan算法求强联通分量)
- 有向图的强联通分量 tarjan