4612 warm up tarjan+bfs求树的直径(重边的强连通通分量)忘了写了,今天总结想起来了。
问加一条边,最少可以剩下几个桥。
先双连通分量缩点,形成一颗树,然后求树的直径,就是减少的桥。
本题要处理重边的情况。
如果本来就两条重边,不能算是桥。
还会爆栈,只能C++交,手动加栈了
别人都是用的双连通分量,我直接无向图改成有向图搞得强连通水过。
- #pragma comment(linker, "/STACK:1024000000,1024000000")
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <stack>
- using namespace std;
- const int maxn = ;
- bool vis[];
- struct edge
- {
- int v,next;
- edge()
- {
- next = -;
- }
- }edges[maxn*-];
- struct ed
- {
- int u,v;
- }e[maxn*-];
- int dfn[],low[],belong[];
- bool inst[];
- int g[maxn];
- vector<int>ng[maxn];
- stack<int>st;
- int bcnt,cnt,time;
- void init(int n)
- {
- int i;
- for(i =;i <= n;i++)
- g[i] = -;
- time = ;bcnt = cnt = ;
- return ;
- }
- void addedge(int u,int v,int val)
- {
- struct edge o;
- edges[cnt].v = v;
- edges[cnt].next = g[u];
- g[u] = cnt;
- cnt++;
- return ;
- }
- void tarjan(int i)
- {
- int j;
- dfn[i] = low[i] = ++time;
- inst[i] = ;
- st.push(i);
- for(j = g[i];j != -;j = edges[j].next)
- {
- if(vis[j]) continue;
- vis[j] = vis[j^] = ;
- int v;
- v = edges[j].v;
- if(!dfn[v])
- {
- tarjan(v);
- low[i] = min(low[i],low[v]);
- }
- else if(inst[v])
- low[i] = min(low[i],dfn[v]);
- }
- int k;
- if(dfn[i] == low[i])
- {
- bcnt++;
- do
- {
- k = st.top();
- st.pop();
- inst[k] = ;
- belong[k] = bcnt;
- }
- while(k != i);
- }
- }
- void tarjans(int n)
- {
- int i;
- bcnt = time = ;
- while(!st.empty())st.pop();
- memset(dfn,,sizeof(dfn));
- memset(inst,,sizeof(inst));
- memset(belong,,sizeof(belong));
- for(i = ;i <= n;i++)
- if(!dfn[i])tarjan(i);
- }
- struct node
- {
- int s,point;
- };
- struct node bfs(int s)
- {
- int i;
- for(i = ;i <= bcnt;i++)
- vis[i] = ;
- queue <struct node>q;
- struct node p;
- p.s = ;p.point = s;
- q.push(p);
- vis[s] = ;
- struct node max;
- max.s = ;
- while(!q.empty())
- {
- struct node now,temp;
- now = q.front();
- q.pop();
- for(i = ;i < ng[now.point].size();i++)
- {
- int v = ng[now.point][i];
- temp.s = now.s+;
- temp.point = v;
- if(!vis[v])
- {
- vis[v] = ;
- // cout<<v<<"***"<<endl;
- if(max.s < temp.s)
- max = temp;
- q.push(temp);
- }
- }
- }
- return max;
- }
- int main()
- {
- int n,m;
- //freopen("in.txt","r",stdin);
- while(scanf("%d %d",&n,&m)&&(n||m))
- {
- int a,b,i;
- init(n);
- memset(vis,,sizeof(vis));
- for(i = ;i < m;i++)
- {
- scanf("%d %d",&e[i].u,&e[i].v);
- addedge(e[i].u,e[i].v,);
- addedge(e[i].v,e[i].u,);
- }
- tarjans(n);
- for(i = ;i <= n;i++)
- {
- ng[i].clear();
- }
- for(i = ;i < m;i++)
- {
- if(belong[e[i].u] == belong[e[i].v])
- continue;
- ng[belong[e[i].u]].push_back(belong[e[i].v]);
- ng[belong[e[i].v]].push_back(belong[e[i].u]);
- }
- struct node max;
- max = bfs();
- max = bfs(max.point);
- printf("%d\n",bcnt-max.s-);
- }
- return ;
- }
4612 warm up tarjan+bfs求树的直径(重边的强连通通分量)忘了写了,今天总结想起来了。的更多相关文章
- HDU4612+Tarjan缩点+BFS求树的直径
tarjan+缩点+树的直径题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少.先tarjan缩点,再在这棵树上求直径.加的边即是连接这条直径的两端. /* tarjan ...
- [USACO2004][poj1985]Cow Marathon(2次bfs求树的直径)
http://poj.org/problem?id=1985 题意:就是给你一颗树,求树的直径(即问哪两点之间的距离最长) 分析: 1.树形dp:只要考虑根节点和子节点的关系就可以了 2.两次bfs: ...
- 牛客小白月赛6C-桃花(DFS/BFS求树的直径)
链接:https://www.nowcoder.com/acm/contest/136/C 来源:牛客网 桃花 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言 ...
- 两次bfs求树的直径的正确性
结论:离树上任意点\(u\)最远的点一定是这颗树直径的一个端点. 证明: 若点\(u\)在树的直径上,设它与直径两个端点\(x,y\)的距离分别为\(S1\).\(S2\),若距离其最远的点\(v\) ...
- hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Su ...
- (求树的直径)Warm up -- HDU -- 4612
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 给一个无向图, 加上一条边后,求桥至少有几个: 那我们加的那条边的两个顶点u,v:一定是u,v之 ...
- HDU-4612 Warm up,tarjan求桥缩点再求树的直径!注意重边
Warm up 虽然网上题解这么多,感觉写下来并不是跟别人竞争访问量的,而是证明自己从前努力过,以后回头复习参考! 题意:n个点由m条无向边连接,求加一条边后桥的最少数量. 思路:如标题,tarjan ...
- 求树的直径+并查集(bfs,dfs都可以)hdu4514
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...
- poj2631 求树的直径裸题
题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...
随机推荐
- Altium Designer Summer 09创建半圆焊盘方法
关于异形焊盘的创建,可参看下面的半圆PAD的制作:1.新建一个PCB文件,然后在里面画一个半圆的Arc,即Place放置(P)>Arc,并且要将其开口处 封闭,即可用Place 放置(P)& ...
- linux gcc loudong
五事九思 (大连Linux主机维护) 大连linux维护qq群:287800525 首页 日志 相册 音乐 收藏 博友 关于我 日志 spcark_0.0.3_i386.src.t ...
- POJ 1759
Garland Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1236 Accepted: 547 Descriptio ...
- POJ 2021
#include <iostream> #include <string> #include <algorithm> #define MAXN 105 using ...
- HDU5569/BestCoder Round #63 (div.2) C.matrix DP
matrix Problem Description Given a matrix with n rows and m columns ( n+m is an odd number ), at fir ...
- android真机自动化测试
appium执行用例时报错问题: 问题解析: 一般该种情况都是因为来连接了多个设备,验证办法:cmd->执行adb devices 看结果是否是多个devices ,如果是这个问题,停掉多余设 ...
- 自动化 测试框架部署(python3+selenium2)
安装Python 从https://www.python.org/downloads/下载最新版本的Python3,请注意,是3: 需要将Python的安装目录和安装目录下的Scripts文件夹添加到 ...
- SSH连接不上Linux的解决方法
SSH连接不上Linux的解决方法: 连续弄了几次,今天早上终于把SSH连接虚拟机连接不通的问题解决了. 先简单说下概要: 主机装的是XP系统,虚拟机用的是red hat Linux. 我用的是nat ...
- Spark源码分析(三)-TaskScheduler创建
原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3879151.html 在SparkContext创建过程中会调用createTaskScheduler函 ...
- C++函数默认参数
C++中允许为函数提供默认参数,又名缺省参数. 使用默认参数时的注意事项: ① 有函数声明(原型)时,默认参数可以放在函数声明或者定义中,但只能放在二者之一 double sqrt(double f ...