题目连接:http://poj.org/problem?id=3177

题目大意是给定一些牧场,牧场和牧场之间可能存在道路相连,要求从一个牧场到另一个牧场要有至少两条以上不同的路径,且路径的每条path是分立的独立的,意为不能有公共道路,问最少添加多少条道路达成题目的要求。

图论问题,因为题目要求不能有公共道路,就是路径不能有公共边。题目转化为求图的边双连通分量,每个边双连通分量内各个牧场肯定存在不同路径可以相互到达,所以要求出图内有多少个边双连通分量,缩点后添边去满足题意。最终缩点后的图为树,所以最简单的办法就是连接树的叶子节点,答案即为树的(叶子节点个数+1)/2。因为是无向图,所以缩点后找到度为1的节点即为叶子节点。

建双向图,直接跑tarjan求BCC,在求BCC的时候注意是遍历边,而非节点。

#include<iostream>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring> using namespace std;
struct node{
vector<int> vex;
vector<int> num;
}; struct edge{
int a,b,id,cut;
}E[5005*2];//a为边的起点,b为边的终点,id为边的输入目录 node g[5005];
int newnode[5005];
int bccnum = 0;
int tot;
int visit[5005],dfn[5005],low[5005];
stack<int> stk; void tarjan(int x,int fa){
dfn[x] = low[x] = ++tot;
stk.push(x);//节点入栈
for(int i = 0;i<g[x].vex.size() ;i++){
int tedge = g[x].num[i]; //边序号,后续可以由边序号作为索引找到该边的id(目录) if(visit[tedge]){
continue;
} visit[tedge] = visit[tedge^1] = 1;//标记双向边已经访问过
if(!dfn[g[x].vex[i]]){ tarjan(g[x].vex[i],x);
low[x] = min(low[x],low[g[x].vex[i]]); if(low[g[x].vex[i]] > dfn[x] ){
E[tedge].cut = E[tedge^1].cut = 1;//该tedge边为割边,做标记
}
}
else
low[x] = min(low[x],dfn[g[x].vex[i]]);
} if(dfn[x] == low[x]){
bccnum++;
//找到一个BCC,依次把这个BCC的节点出栈,并做缩点操作
int v;
do
{
v = stk.top() ;
//visit[v] = 0;
stk.pop();
newnode[v] = bccnum;// v节点所属‘bccnum’的边双连通分量
}while(v != x);
}
} int edgenum = 0;//边的序号从0开始,因为是建立双向边所以两条边标记的序号是异或关系,由边序号可以找到该边的id
void addedge(int u,int v,int id){ E[edgenum].a = u;
E[edgenum].b = v;
g[u].num.push_back(edgenum);
E[edgenum++].id = id;
} int main(){
int F,R;
cin>>F>>R;
for(int i = 1;i<=R;i++){
int u,v;
cin>>u>>v;
addedge(u,v,i);
addedge(v,u,i);
g[u].vex.push_back(v);
g[v].vex.push_back(u);
} for(int i = 1;i<=F;i++){
if(!dfn[i]){
tarjan(i,0);
}
}
node newG[bccnum+1];
//cout<<bccnum<<endl;
int mark[bccnum+1];
memset(mark,0,sizeof(mark));
for(int i = 1;i<=F;i++){
for(int j = 0;j<g[i].vex.size() ;j++ ){
if(E[g[i].num[j]].cut ){ //找到了一个割边
mark[newnode[g[i].vex[j]]] ++;//缩点后该BCC的度++
}
}
}
int ans = 0;
for(int i = 1;i<=bccnum;i++){
if(mark[i] == 1){//缩点后度为1的BCC进行统计
//cout<<"x";
ans++;
}
}
cout<<(ans+1)/2;
return 0;
}

POJ 3177 Redundant Paths (tarjan边双连通分量)的更多相关文章

  1. POJ 3177 Redundant Paths(边双连通分量)

    [题目链接] http://poj.org/problem?id=3177 [题目大意] 给出一张图,问增加几条边,使得整张图构成双连通分量 [题解] 首先我们对图进行双连通分量缩点, 那么问题就转化 ...

  2. POJ 3177 Redundant Paths(边双连通的构造)

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13717   Accepted: 5824 ...

  3. POJ - 3177 Redundant Paths (边双连通缩点)

    题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...

  4. POJ 3177 Redundant Paths 无向图边双联通基础题

    题意: 给一个无向图,保证任意两个点之间有两条完全不相同的路径 求至少加多少边才能实现 题解: 得先学会一波tarjan无向图 桥的定义是:删除这条边之后该图不联通 一条无向边(u,v)是桥,当且仅当 ...

  5. tarjan算法求桥双连通分量 POJ 3177 Redundant Paths

    POJ 3177 Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12598   Accept ...

  6. POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)

    POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...

  7. poj 3177 Redundant Paths(边双连通分量+缩点)

    链接:http://poj.org/problem?id=3177 题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任 ...

  8. [双连通分量] POJ 3177 Redundant Paths

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13712   Accepted: 5821 ...

  9. POJ 3177 Redundant Paths & POJ 3352 Road Construction(双连通分量)

    Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numb ...

随机推荐

  1. 关于Windows系统下端口被占用的问题和task命令

    一.如何解决端口被占用的问题? 此时端口4444被进程占用,只要找到端口4444的进程,并且将进程kill掉即可. 开始--运行--cmd 进入命令提示符 输入netstat -aon 即可看到所有连 ...

  2. 设置 myeclipse 编码格式

    参考网址:https://jingyan.baidu.com/article/77b8dc7fc6e1626174eab6bb.html

  3. python3练习100题——040

    原题链接:http://www.runoob.com/python/python-exercise-example40.html 题目:将一个数组逆序输出. a=[1,2,3,4,5] print a ...

  4. PHP 冷知识

    1,执行Linux命令 <?php $a =`ls -a /`; // execute linux command echo '<pre>'.$a; 2.为变量起别名 <?ph ...

  5. 133.在django中使用memcached

    1. 在django中使用memcached,可以在settings.py文件中DATABASES变量下面配置CACHES缓存相关配置信息,只允许本机连接memcached就可以设置LOCATION为 ...

  6. C++基类、派生类、虚函数的几个知识点

    1.尽管派生类中含有基类继承来的成员,但派生类初始化这部分变量需要调用基类的构造函数. class A { private: int x; virtual void f(){cout<<& ...

  7. Log4net实用说明

    Log4net实用说明 Appender Filter Layout Logger ObjectRender Repository PatterLayout格式化字符表 配置文件说明 Appender ...

  8. Leetcode Week3 Merge Two(k) Sorted Lists

    Question Q1.Merge two sorted linked lists and return it as a new list. The new list should be made b ...

  9. wso2 使用配置

    1.下载wso2 https://docs.wso2.com 2.配置 https://172.10.0.59:9443/publisher https://172.10.0.59:9443/carb ...

  10. C语言-浮点数的秘密

    一.浮点数的秘密 1.内存中的浮点数 浮点数在内存中的存储方式为:符号位.指数.尾数 十进制浮点数的内存表示: 实例分析: #include <stdio.h> //打印十进制的内存表示 ...