问加一条边,最少可以剩下几个桥。

先双连通分量缩点,形成一颗树,然后求树的直径,就是减少的桥。

本题要处理重边的情况。

如果本来就两条重边,不能算是桥。

还会爆栈,只能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求树的直径(重边的强连通通分量)忘了写了,今天总结想起来了。的更多相关文章

  1. HDU4612+Tarjan缩点+BFS求树的直径

    tarjan+缩点+树的直径题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少.先tarjan缩点,再在这棵树上求直径.加的边即是连接这条直径的两端. /* tarjan ...

  2. [USACO2004][poj1985]Cow Marathon(2次bfs求树的直径)

    http://poj.org/problem?id=1985 题意:就是给你一颗树,求树的直径(即问哪两点之间的距离最长) 分析: 1.树形dp:只要考虑根节点和子节点的关系就可以了 2.两次bfs: ...

  3. 牛客小白月赛6C-桃花(DFS/BFS求树的直径)

    链接:https://www.nowcoder.com/acm/contest/136/C 来源:牛客网 桃花 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言 ...

  4. 两次bfs求树的直径的正确性

    结论:离树上任意点\(u\)最远的点一定是这颗树直径的一个端点. 证明: 若点\(u\)在树的直径上,设它与直径两个端点\(x,y\)的距离分别为\(S1\).\(S2\),若距离其最远的点\(v\) ...

  5. hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Su ...

  6. (求树的直径)Warm up -- HDU -- 4612

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 给一个无向图, 加上一条边后,求桥至少有几个: 那我们加的那条边的两个顶点u,v:一定是u,v之 ...

  7. HDU-4612 Warm up,tarjan求桥缩点再求树的直径!注意重边

    Warm up 虽然网上题解这么多,感觉写下来并不是跟别人竞争访问量的,而是证明自己从前努力过,以后回头复习参考! 题意:n个点由m条无向边连接,求加一条边后桥的最少数量. 思路:如标题,tarjan ...

  8. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  9. poj2631 求树的直径裸题

    题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...

随机推荐

  1. 利用Jquery实现http长连接(LongPoll) {转}

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="JqueryAjaxLongPo ...

  2. POJ 1953

    //FINBONACI数列 #include <iostream> #define MAXN 100 using namespace std; int _m[MAXN]; int main ...

  3. POJ 1419

    #include <iostream> #define MAXN 105 #define max _max using namespace std; int j; bool _m[MAXN ...

  4. POJ 1552

    #include<iostream> using namespace std; int main() { ]; int i,j; ; do{ sum=; ;num[i-]!=&&a ...

  5. 免安装jdk 和 免安装tomcat

    免安装tomcat 运行的时候要执行免安装的 jdk,可以进行如下设置. 在 startup.bat 里加上这么一句, set "JAVA_HOME=C:\jdk1.6.0_43"

  6. 2016PHP开发者大会

    大会干货: Rasmus Lerdorf——<Speeding up the Web with PHP 7> PHP 7 is here. It brings drastic perfor ...

  7. Good Bye 2014 D. New Year Santa Network 图论+期望

    D. New Year Santa Network   New Year is coming in Tree World! In this world, as the name implies, th ...

  8. Windows PAE 寻址

    PAE 就是物理地址扩展.我们常规的寻址方式是之前的将虚拟地址化为10 10 12的方式来寻址页目录,页表,页偏移,但是在开始PAE之后的寻址方式发生了改变,将32位的虚拟地址转化成 2 9 9 12 ...

  9. Windows X64 Patch Guard

    先简单介绍下PatchGuard ,摘自百度百科 PatchGuard就是Windows Vista的内核保护系统,防止任何非授权软件试图“修改”Windows内核,也就是说,Vista内核的新型金钟 ...

  10. lintcode:二叉树的路径和

    题目 给定一个二叉树,找出所有路径中各节点相加总和等于给定 目标值 的路径. 一个有效的路径,指的是从根节点到叶节点的路径. 解题 下面有个小bug 最后比较的时候是叶子节点为空,左右都有叶子结点,所 ...