POJ3177(无向图变双连通图)
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11514 | Accepted: 4946 |
Description
Given a description of the current set of R (F-1 <= R <= 10,000) paths that each connect exactly two different fields, determine the minimum number of new paths (each of which connects exactly two fields) that must be built so that there are at least two separate routes between any pair of fields. Routes are considered separate if they use none of the same paths, even if they visit the same intermediate field along the way.
There might already be more than one paths between the same pair of fields, and you may also build a new path that connects the same fields as some other path.
Input
Lines 2..R+1: Each line contains two space-separated integers which are the fields at the endpoints of some path.
Output
Sample Input
7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
Sample Output
2
题意:给定一个连通图,问至少加几条边可使这个图为双连通的。
思路:将原图G的双连通分量浓缩为一个点得到图G',则答案为(图G'中的叶子个数+1)/2。
存在重边
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=;
bool mp[MAXN][MAXN];//存在重边用邻接矩阵,用int的话会MLE
int n,m;
int dfn[MAXN],low[MAXN],time;
int stack[MAXN],top;
int ins[MAXN];
int belong[MAXN],cnt;
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++time;
stack[top++]=u;
ins[u]=true;
for(int v=;v<=n;v++)
{
if(mp[u][v])
{
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else if(v!=fa&&ins[v]) low[u]=min(low[u],dfn[v]);
}
} if(dfn[u]==low[u])//连通分量,发现一个处理一个
{
int v;
cnt++;
do{
v=stack[--top];
ins[v]=false;
belong[v]=cnt;
}while(u!=v);
}
}
int deg[MAXN];
void cal()
{
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
if(mp[i][j]&&belong[i]!=belong[j])
{
deg[belong[i]]++;
deg[belong[j]]++;
}
}
int res=;
for(int i=;i<=cnt;i++)
{
if(deg[i]==)
res++;
}
printf("%d\n",(res+)/);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(ins,false,sizeof(ins));
time=;
cnt=;
memset(belong,,sizeof(belong));
memset(mp,false,sizeof(mp));
memset(deg,,sizeof(deg));
for(int i=;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
mp[u][v]=mp[v][u]=true;
}
tarjan(,-);
cal(); }
}
tarjan算法模板:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=;
vector<int> mp[MAXN];
int n,m;
int dfn[MAXN],low[MAXN],index;
int bridge[MAXN];
int critical[MAXN];
int root;
int stack[MAXN],top;
bool ins[MAXN];
int belong[MAXN],cnt;
void tarjan(int u,int fa)
{
stack[u]=top++;
ins[u]=true;
dfn[u]=low[u]=++index;
int son=;
for(int i=;i<mp[u].size();i++)
{
int v=mp[u][i];
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
son++;
if((u==root&&son>)||(u!=root&&dfn[u]<=low[v]))
{
critical[u]=;
}
if(dfn[u]<low[v])
{
bridge[v]=;
}
}
else if(v!=fa) low[u]=min(dfn[v],low[u]);
}
if(dfn[u]==low[u])
{
int v;
cnt++;
do{
v=stack[--top];
ins[v]=false;
belong[v]=cnt;
}while(u!=v);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
mp[u].push_back(v);
mp[v].push_back(u);
}
for(int i=;i<=n;i++)
if(!dfn[i])
{
root=i;
tarjan(i,-);
} printf("割点分别为:\n");
for(int i=;i<=n;i++)
{
if(critical[i])
printf("%d ",i);
}
printf("\n");
printf("割边一端的节点为:\n");
for(int i=;i<=n;i++)
{
if(bridge[i])
printf("%d ",i);
}
printf("\n");
printf("连通分量数目为:\n");
printf("%d\n",cnt);
return ;
}
/*
5 6
1 2
1 3
2 3
3 4
4 5
3 5
*/
POJ3177(无向图变双连通图)的更多相关文章
- POJ 3177--Redundant Paths【无向图添加最少的边成为边双连通图 && tarjan求ebc && 缩点构造缩点树】
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10798 Accepted: 4626 ...
- poj3177 && poj3352 边双连通分量缩点
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12676 Accepted: 5368 ...
- poj3177(边双连通分量+缩点)
传送门:Redundant Paths 题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立 ...
- POJ3177 Redundant Paths 双连通分量
Redundant Paths Description In order to get from one of the F (1 <= F <= 5,000) grazing fields ...
- 『Tarjan算法 无向图的双联通分量』
无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...
- POJ3352Road Construction(构造双连通图)sdut2506完美网络
构造双连通图:一个有桥的连通图,如何把它通过加边变成边双连通图? 一个有桥的连通图,如何把它通过加边变成边双连通图?方法为首先求出所有的桥,然后删除这些桥边,剩下的每个连通块都是一个双连通子图.把每个 ...
- POJ 3177——Redundant Paths——————【加边形成边双连通图】
Redundant Paths Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- Road Construction(无向图的双连通分量)
http://poj.org/problem?id=3352 题意:给出一个有n个顶点m条边的无向连通图,问至少添加几条边,使删除任意一条边原图仍连通. 思路:一个边双连通图删除任意一条边仍为连通图. ...
- [Tarjan系列] Tarjan算法求无向图的双连通分量
这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...
随机推荐
- Effective Java - [3. 对象通用方法]
Item 10. 若覆盖equals方法,需要遵守规则
- The Google File System论文拜读
The Google File System Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung Google∗ 摘要 我们设计并实现了谷歌文件系统 ...
- Content encoding error问题解决方法
A few people have been experiencing the following error. UPDATE: The reason for it happening is beca ...
- jQuery+bootstrap实现美化警告/确认/提示对话框插件
http://www.html580.com/12067/demo http://craftpip.github.io/jquery-confirm/
- iphone开发之获取网卡的MAC地址和IP地址
本文转载至 http://blog.csdn.net/arthurchenjs/article/details/6358489 这是获取网卡的硬件地址的代码,如果无法编译通过,记得把下面的这几个头文件 ...
- maven工作的过程
1 建立各个module之间的依赖关系 2 越底层的依赖的module先生成 3 下载远程库中的依赖 4 先生成本地被依赖的module 问题是,如何保证本次module和远程库中的包不重名?
- json (js对象标记)
基础 JSON: JavaScript Object Notation (JavaScript对象表示法) 网络媒体类型是 application/json,文件名扩展是 .json JSON 独立于 ...
- 关于Wix的源代码
Wix的源代码有两种方式可以获得,以3.8为例: 在Release的页面下载wix38-debug.zip 通过SourceCode页面下载,http://wix.codeplex.com/Sourc ...
- win7怎么设置打印机共享
一.设置好家庭组,让客户机加入家庭组 二.对服务机的打印机进行共享设置,如果保存不成功请在计算机服务那里打开防火墙 三.1.开启guest用户,具体操作:我的电脑右击---管理---本地用户和组--开 ...
- 简单Android代码混淆(转)
代码混淆步骤: 1,project.properties中打开代码混淆功能,加入proguard.config=proguard.cfg 2,编辑proguard.cfg文件,项目没有自动生成时可手工 ...