题目链接

Warm up

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 5353    Accepted Submission(s): 1195

Problem Description
  N planets are connected by M bidirectional channels that allow instant transportation. It's always possible to travel between any two planets through these channels.
  If we can isolate some planets from others by breaking only one channel , the channel is called a bridge of the transportation system.
People don't like to be isolated. So they ask what's the minimal number of bridges they can have if they decide to build a new channel.
  Note that there could be more than one channel between two planets.
 
Input
  The input contains multiple cases.
  Each case starts with two positive integers N and M , indicating the number of planets and the number of channels.
  (2<=N<=200000, 1<=M<=1000000)
  Next M lines each contains two positive integers A and B, indicating a channel between planet A and B in the system. Planets are numbered by 1..N.
  A line with two integers '0' terminates the input.
 
Output
  For each case, output the minimal number of bridges after building a new channel in a line.
 
Sample Input
4 4
1 2
1 3
1 4
2 3
0 0
 
Sample Output
0
给一个图, 求增加一条边之后的桥的数量最少是多少。有重边
 
缩点然后找树的直径, 答案就是缩点之后的边数-直径。
tarjan的时候注意, vis数组记录访问过的边的编号而不是点。
找树的直径最好写bfs, dfs据说爆栈
详细看代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define fi first
#define se second
typedef pair<int, int> pll;
const int inf = ;
const int maxn = 2e5+;
const int maxe = 1e6+;
int head[maxn], head1[maxn], dis[maxn], num, num1, top, cnum, instack[maxn], st[maxn], dfn[maxn], low[maxn], s[maxn];
int maxx, pos, vis[maxe*], cnt;
struct node
{
int to, nextt;
}e[maxe*], e1[maxe*];
void add(int u, int v) {
e[num].to = v, e[num].nextt = head[u], head[u] = num++;
}
void add1(int u, int v) {
e1[num1].to = v, e1[num1].nextt = head1[u], head1[u] = num1++;
}
void init() {
num = num1 = cnt = cnum = top = ;
mem1(head);
mem(s);
mem(vis);
mem1(head1);
mem(instack);
mem(st);
mem(dfn);
mem(low);
mem(dis);
}
pll edge[maxe];
void tarjan(int u) {
instack[u] = ;
st[top++] = u;
dfn[u] = low[u] = ++cnt;
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(vis[i])
continue;
vis[i] = vis[i^] = ;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(instack[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]) {
++cnum;
int x;
do {
x = st[--top];
instack[x] = ;
s[x] = cnum;
} while(x != u);
}
}
void bfs(int u) {
queue <int> q;
q.push(u);
mem2(dis);
dis[u] = ;
mem(vis);
vis[u] = ;
maxx = , pos = u;
while(!q.empty()) {
int v = q.front(); q.pop();
for(int i = head1[v]; ~i; i = e1[i].nextt) {
int ve = e1[i].to;
if(vis[ve])
continue;
vis[ve] = ;
dis[ve] = dis[v]+;
if(dis[ve]>maxx) {
maxx = dis[ve];
pos = ve;
}
q.push(ve);
}
}
}
int main()
{
int n, m, x, y;
while(cin>>n>>m) {
if(n+m==)
break;
init();
for(int i = ; i<m; i++) {
scanf("%d%d", &x, &y);
edge[i].fi = x, edge[i].se = y;
add(x, y);
add(y, x);
}
tarjan();
int edgenum = ;
for(int i = ; i<m; i++) {
int x = edge[i].fi, y = edge[i].se;
if(s[x]!=s[y]) {
add1(s[x], s[y]);
add1(s[y], s[x]);
edgenum++;
}
}
bfs(s[]);
bfs(pos);
int ans = edgenum-maxx;
printf("%d\n", ans);
}
return ;
}

hdu 4612 Warm up 有重边缩点+树的直径的更多相关文章

  1. hdu 4612 Warm up 双连通缩点+树的直径

    首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...

  2. Hdu 4612 Warm up (双连通分支+树的直径)

    题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...

  3. HDU 4612 Warm up(双连通分量缩点+求树的直径)

    思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...

  4. HDU 4612 Warm up 连通图缩点

    题目大意:给出一个连通图,求再一个边后,剩余的最少桥数. 题目思路:首先进行缩点得到重构后的图,求出重构后树的直径(通过两次BFS求出相距最远的两点间的距离),ans=重构图边数-树的直径 //#pr ...

  5. F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解

    题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...

  6. HDU 4612 Warm up —— (缩点 + 求树的直径)

    题意:一个无向图,问建立一条新边以后桥的最小数量. 分析:缩点以后,找出新图的树的直径,将这两点连接即可. 但是题目有个note:两点之间可能有重边!而用普通的vector保存边的话,用v!=fa的话 ...

  7. HDU 4612 Warm up (边双连通分量+缩点+树的直径)

    <题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...

  8. HDU 4612——Warm up——————【边双连通分量、树的直径】

    Warm up Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  9. 【HDU 4612 Warm up】BCC 树的直径

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...

随机推荐

  1. OC中两个关键字的作用:@property和@synthesize

    两个关键字的使用:@property和@synthesize 一.@property关键字这个关键字是OC中能够快速的定义一个属性的方式,而且他可以设置一些值,就可以达到一定的效果,比如引用计数的问题 ...

  2. node.js 中的全局对象

    /** * Created by Administrator on 2016/8/29. */ const http = require("http"); const hostna ...

  3. 安卓Xpost框架

    http://pcedu.pconline.com.cn/484/4841077_all.html

  4. cocos2dx3.3在Windows环境搭建以及新工程创建

    这个虽然比较简单,但是是学习cocos的第一步,不积跬步无以至千里,所以今天先分享Windows下环境搭建问题.关于mac搭建后续有机会在写(ps:因为我暂时没有mac),anyway,开始吧! 首先 ...

  5. WGS84、GCJ-02(火星坐标)、百度坐标,Web墨卡托坐标

    GCJ-02坐标系统(火星坐标)简介:http://blog.csdn.net/giswens/article/details/8775121(存档:http://mapbd.com/cms/2012 ...

  6. GetMemory()函数

    NO1 void GetMemory(char *p) { p=(char *)malloc(100); } void Test() { char * str=NULL; GetMemory(str) ...

  7. Robot Framework中DatabaseLibrary应用

    DatabaseLibrary: 在RF的官网上,有DatabaseLibrary的下载链接,DatabaseLibrary有2个版本,Python和Java版.本人使用的是Python版本. 1.下 ...

  8. python request的运用

    requests是python的一个HTTP客户端库,跟urllib,urllib2类似,那为什么要用requests而不用urllib2呢?官方文档中是这样说明的: python的标准库urllib ...

  9. Bash debug

    Debugging bash scripts Bash can help us to find problems in bash scripts in some ways. You don't exp ...

  10. 提示text还能输入多少字节

    1.添加jQuery自定义扩展 $(function($){ // tipWrap: 提示消息的容器 // maxNumber: 最大输入字符 $.fn.artTxtCount = function( ...