题意:有一个无向连通图,现在问添加一条边后最少还有几个桥
分析:先把图缩点,然后重构图为一棵树,求出来树的直径即可,不过注意会有重边,构树的时候注意一下
***********************************************************************
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std; const int MAXN = 2e5+; struct Edge{int v, vis, next;}e1[MAXN*], e2[MAXN*];
int Head1[MAXN], Head2[MAXN], cnt[], fa[MAXN];
void AddEdge(Edge e[], int Head[], int u, int v, int k)
{
    e[ cnt[k] ].v = v;
    e[ cnt[k] ].vis = ;
    e[ cnt[k] ].next = Head[u];
    Head[u] = cnt[k]++;
} struct node{int u, step;};
node BFS(node s, int k)
{
    queue<node> Q;
    Q.push(s);     while(Q.size())
    {
        s = Q.front();Q.pop();         for(int j=Head2[s.u]; j!=-; j=e2[j].next)
        {
            node q = s;
            q.u = e2[j].v;             if(e2[j].vis != k)
            {
                e2[j].vis = e2[j^].vis = k;
                q.step++;
                Q.push(q);
            }
        }     }     return s;
} int dfn[MAXN], low[MAXN], Index;
int belong[MAXN], bnt;
int Stack[MAXN], top; void InIt(int N)
{
    cnt[] = cnt[] = Index = bnt = top = ;
    for(int i=; i<=N; i++)
    {
        Head1[i] = Head2[i] = -;
        dfn[i] = ;
        fa[i] = ;
    }
}
void Tarjan(int u)
{
    int v;     low[u] = dfn[u] = ++Index;
    Stack[++top] = u;     for(int j=Head1[u]; j!=-; j=e1[j].next)
    {
        v = e1[j].v;
        if(e1[j].vis == false)
        {
            e1[j].vis = e1[j^].vis = true;
            if( !dfn[v] )
            {
                Tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else
                low[u] = min(low[u], dfn[v]);
        }
    }     if(low[u] == dfn[u])
    {
        ++bnt;
        do
        {
            v = Stack[top--];
            belong[v] = bnt;
        }
        while(u != v);
    }
}
int main()
{
    int N, M;     while(scanf("%d%d", &N, &M), N+M)
    {
        int i, j, u, v;         InIt(N);         while(M--)
        {
            scanf("%d%d", &u, &v);
            AddEdge(e1, Head1, u, v, );
            AddEdge(e1, Head1, v, u, );
        }         Tarjan();         for(i=; i<=N; i++)
        for(j=Head1[i]; j!=-; j=e1[j].next)
        {
            v = e1[j].v;
            u = belong[i], v = belong[v];
            if(u > v && fa[v] != u)
            {
                fa[v] = u;
                AddEdge(e2, Head2, u, v, );
                AddEdge(e2, Head2, v, u, );
            }
        }         node s;
        s.u = , s.step = ;         s = BFS(s, );
        s.step = ;
        s = BFS(s, );         printf("%d\n", bnt-s.step-);
    }     return ; } 

F - Warm up - hdu 4612(缩点+求树的直径)的更多相关文章

  1. hdu 4607 Park Visit 求树的直径

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...

  2. HDU 4607 Park visit (求树的直径)

    解题思路: 通过两次DFS求树的直径,第一次以随意点作为起点,找到距离该点距离最远的点,则能够证明这个点一定在树的直径上,然后以该点为起点进行DFS得到的最长路就是树的直径. 最后的询问,假设K &l ...

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

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

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

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

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

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

  6. hdu4612 无向图中随意加入一条边后使桥的数量最少 / 无向图缩点+求树的直径

    题意如上,含有重边(重边的话,俩个点就能够构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选随意起点U,进行bfs,到达最远的一个点v ...

  7. hdu4612 无向图中任意添加一条边后使桥的数量最少 / 无向图缩点+求树的直径

    题意如上,含有重边(重边的话,俩个点就可以构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选任意起点U,进行bfs,到达最远的一个点v ...

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

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

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

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

随机推荐

  1. 剪切板 复制文本 ClipboardManager

    代码 public class MainActivity extends ListActivity {     private EditText tv_info;     private Clipbo ...

  2. java判断不为空

    因为java是强类型语言,所以判断空的时候分null 和字符串空 if(userID == null || "".equals(userID)){ response.sendRed ...

  3. Android 开发笔记——对应用进行单元测试

    在实际开发中,开发android软件的过程需要不断地进行测试.而使用Junit测试框架,是正规Android开发的必用技术, 在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性. 第一 ...

  4. Jquery 操作 select

    1.判断select选项中 是否存在Value="paraValue"的Item $("#selectid option[@value='paraValue']" ...

  5. NSURLConnection下载

    @interface AppDelegate () <NSURLConnectionDataDelegate> {    NSMutableData *mData;} @end @impl ...

  6. caption标签,为表格添加标题和摘要

    表格还是需要添加一些标签进行优化,可以添加标题和摘要.代码如下: 摘要 摘要的内容是不会在浏览器中显示出来的.它的作用是增加表格的可读性(语义化),使搜索引擎更好的读懂表格内容,还可以使屏幕阅读器更好 ...

  7. Swift - 05 - 数值型字面量

    //: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...

  8. [转载]__type_traits

    在STL中为了提供通用的操作而又不损失效率,我们用到了一种特殊的技巧,叫traits编程技巧.具体的来说,traits就是 通过定义一些结构体或类,并利用模板类特化和偏特化的能力,给类型赋予一些特性, ...

  9. 使用C++11 实现的线程池

    最近打算做一个服务器端程序,每来一个客户端请求新开一个线程进行处理.在网上查了一些资料后,准备使用线程池来做这个东西.使用C++11新的库处理想线程问题比以前简单了许多,在网上找到一份线程池的实现,h ...

  10. META http-equiv 大全

    META http-equiv 大全 HTTP-EQUIV类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正确和精确地显示网页内容.常用的HTTP-EQUIV类型有: 1.Content ...