poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)
- /**
- problem: http://poj.org/problem?id=3177
- tarjan blog: https://blog.csdn.net/reverie_mjp/article/details/51704523
- v 为下一结点, u为当前结点
- 如果low[v] > dfn[u] 则 边(u,v)为桥
- 缩点后剩下的所有边都为桥(缩点后即为树结构)
- 将叶子结点相连使其成为双联通分量为最优解
- 所以:
- 添加(leaf + 1) / 2 条边即可使图成为双联通图
- **/
- #include<stdio.h>
- #include<stack>
- #include<algorithm>
- using namespace std;
- class Graphics{
- const static int MAXN = ;
- const static int MAXM = * ;
- private:
- struct Edge{
- int to, next;
- bool bridge;
- }edge[MAXM];
- struct Point{
- int dfn, low, color;
- }point[MAXN];
- int first[MAXN], sign, sumOfPoint, dfnNum, colorNum;
- bool vis[MAXN];
- stack<int> stk;
- void tarjan(int u, int preEdge = -){
- point[u].low = dfnNum;
- point[u].dfn = dfnNum ++;
- vis[u] = true;
- stk.push(u);
- for(int i = first[u]; i != -; i = edge[i].next){
- int to = edge[i].to;
- if((i^) == preEdge) continue; /// 由于是双向边,防止由该边跑回原来的点
- if(!point[to].dfn){
- tarjan(to, i);
- point[u].low = min(point[u].low, point[to].low);
- if(point[to].low > point[u].dfn){
- edge[i].bridge = true;
- edge[i^].bridge = true;
- }
- }else if(vis[to]){
- point[u].low = min(point[to].dfn, point[u].low);
- }
- }
- if(point[u].dfn == point[u].low){
- vis[u] = false;
- point[u].color = ++ colorNum;
- while(stk.top() != u){
- point[stk.top()].color = colorNum;
- vis[stk.top()] = false;
- stk.pop();
- }
- stk.pop();
- }
- }
- public:
- void init(int n){
- sumOfPoint = n;
- for(int i = ; i <= n; i ++){
- first[i] = -;
- vis[i] = ;
- }
- sign = colorNum = ;
- dfnNum = ;
- }
- void addEdgeOneWay(int u, int v){
- edge[sign].to = v;
- edge[sign].next = first[u];
- edge[sign].bridge = false;
- first[u] = sign ++;
- }
- void addEdgeTwoWay(int u, int v){
- addEdgeOneWay(u, v);
- addEdgeOneWay(v, u);
- }
- void tarjanAllPoint(){
- for(int i = ; i <= sumOfPoint; i ++){
- if(!point[i].dfn)
- tarjan(i);
- }
- }
- int getAns(){
- int *degree = new int[sumOfPoint+];
- int ans = ;
- for(int i = ; i <= sumOfPoint; i ++){
- degree[i] = ;
- }
- tarjanAllPoint();
- for(int i = ; i <= sumOfPoint; i ++){
- for(int j = first[i]; j != -; j = edge[j].next){
- int to = edge[j].to;
- if(edge[j].bridge){
- degree[point[to].color] ++;
- }
- }
- }
- for(int i = ; i <= sumOfPoint; i ++){
- if(degree[i] == ){
- ans ++;
- }
- }
- delete []degree; return (ans + ) / ;
- }
- }graph;
- int main(){
- int f, r;
- scanf("%d%d", &f, &r);
- graph.init(f);
- while(r --){
- int a, b;
- scanf("%d%d", &a, &b);
- graph.addEdgeTwoWay(a, b);
- }
- printf("%d\n", graph.getAns());
- return ;
- }
ps:
- 防止由该边跑回原来的点不能判断(点)而要判断(边)即
- 这么写是有bug的
例如:重边
poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)的更多相关文章
- tarjan算法求桥双连通分量 POJ 3177 Redundant Paths
POJ 3177 Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12598 Accept ...
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...
- poj 3177 Redundant Paths(tarjan边双连通)
题目链接:http://poj.org/problem?id=3177 题意:求最少加几条边使得没对点都有至少两条路互通. 题解:边双连通顾名思义,可以先求一下连通块显然连通块里的点都是双连通的,然后 ...
- poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11047 Accepted: 4725 ...
- POJ 3177 Redundant Paths(边双连通的构造)
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13717 Accepted: 5824 ...
- POJ 3177——Redundant Paths——————【加边形成边双连通图】
Redundant Paths Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ 3177 Redundant Paths (tarjan边双连通分量)
题目连接:http://poj.org/problem?id=3177 题目大意是给定一些牧场,牧场和牧场之间可能存在道路相连,要求从一个牧场到另一个牧场要有至少两条以上不同的路径,且路径的每条pat ...
- POJ 3177 Redundant Paths(Tarjan)
题目链接 题意 : 一个无向连通图,最少添加几条边使其成为一个边连通分量 . 思路 :先用Tarjan缩点,缩点之后的图一定是一棵树,边连通度为1.然后找到所有叶子节点,即度数为1的节点的个数leaf ...
- POJ - 3177 Redundant Paths (边双连通缩点)
题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...
随机推荐
- python爬取英语学习资料并发送邮件
新建发送邮件类 import smtplib from email.mime.text import MIMEText from email.header import Header class Se ...
- 安装VS2013时,如何避开IE10的限制
安装VS2013时,如何避开IE10的限制 VS就会告诉我们目前环境不适合安装VS2013,必须升级IE版本到IE10. 如果不想安装IE10,有没有办法呢? 答案肯定是有的. 将下面一段文字,储存为 ...
- 前端之CSS——盒子模型和浮动
一.CSS盒子模型 HTML文档中的每个元素都被描绘成矩形盒子,这些矩形盒子通过一个模型来描述其占用空间,这个模型称为盒子模型. 盒子模型通过四个边界来描述:margin(外边距),border(边框 ...
- node:fs-extra模块
var fs = require('fs-extra'); //复制 并会覆盖已有文件 fs.copy('./demo/index.html','./demo/index2.html' ,(err) ...
- Angular选项卡
前几天我发的东西,可能对于没有基础的人很难理解,那么今天,咱们就发点简单点的东西吧! Angular显示隐藏,选项卡! 还是那句话,话不多说,上代码: <!DOCTYPE html> &l ...
- git本地分支重命名
1. 本地分支重命名 git branch -m oldbranchname newbranchname 2. 远程分支重命名 (假设本地分支和远程对应分支名称相同) a. 重命名远程分支对应的本地分 ...
- hibernate_ID生成策略
increment:主键按数值顺序递增.此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键.这种方式可能产生的问题是:如果当前有多个实例 ...
- 搭建JUnit环境
1.下载 JUnit,这里用JUnit 4.7 下载链接: http://pan.baidu.com/s/1c23n7LQ 密码: i18e 2.可以直接 build path 引入:也可以创建 Us ...
- Oracle 查看session级别信息
1. 查看活动会话信息[sql] view plain copySELECT * FROM V$SESSION WHERE USERNAME IS NOT NULL AND STAT ...
- JS入口函数和JQuery入口函数
首先,讲一下它们的区别: (1)JS的window.onload事件必须要等到所有内容,以及外部图片之类的文件加载完之后,才会去执行. (2)JQuery入口函数是在所有标签加载完之后,就会去执行. ...