题目连接: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. 接口测试(http 和 rpc)

    接口测试主要分HTTP和RPC两类,RPC类型里面以Dubbo较为知名.互联网微服务架构,两种接口都需要做接口测试的,不管是业务测试还是回归测试: Dubbo:Java栈的互联网公司比如阿里.美团.5 ...

  2. rp算法 随机化 刷题记录

    刷随机化是真的会上瘾quq 洛谷P3973 [TJOI2015]线性代数 看oiwiki上说可以随机化...于是... 就随机在a[i]上选一位取反,然后更新答案,最后输出答案. ...无话可说 代码 ...

  3. linux - mysql:启动 mysql

    启动mysql 第一种: /etc/rc.d/init.d/mysqld start /etc/rc.d/init.d/mysqld stop 第二种:使用service 启动.关闭MySQL服务 s ...

  4. IIS 部署asp.net Core程序注意事项

    Install the .NET Core Windows Server Hosting bundle Install the.NET Core Runtime 修改应用程序池的.net framew ...

  5. 洛谷P1086 花生采摘

    https://www.luogu.org/problem/P1086 #include <bits/stdc++.h> using namespace std; typedef long ...

  6. Windows下解决github push failed (remote: Permission to userA/XXXX.git denied to userB.) 上传gitHub失败报错

    Windows环境下解决 github push failed (remote: Permission to userA/XXXX.git denied to userB.) · 初学GitHub的朋 ...

  7. Java类、方法、属性等

    java是面向对象的编程语言 Object,就是指面向对象的对象,对象就是类的具体实例. 在java里,对象是类的一个具体实例.就像:人,指一个类.张三.李四.王五等则是一个个具体的实例,也就是jav ...

  8. [BZOJ3277/BZOJ3473] 串 - 后缀数组,二分,双指针,ST表,均摊分析

    [BZOJ3277] 串 Description 现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Solution 首先将所有串连 ...

  9. SP1716 GSS3 - Can you answer these queries III - 动态dp,线段树

    GSS3 Description 动态维护最大子段和,支持单点修改. Solution 设 \(f[i]\) 表示以 \(i\) 为结尾的最大子段和, \(g[i]\) 表示 \(1 \sim i\) ...

  10. plt/sns draw histgram

    当使用如下代码保存使用 plt.savefig 保存生成的图片时,结果打开生成的图片却是一片空白. import matplotlib.pyplot as pltx = np.triu(ged) # ...