zoukankan      html  css  js  c++  java
  • HDU

    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

    给出一个连通图

    让你加一条路 求最小的桥数

    那么我们缩点之后 这个问题就转化成了树的问题

    我们只需要求树的最长一条链即可

    树上的最长的链也叫树的直径

    简单说一下树的直径的求法

    对于一棵树任取一点跑dfs那么据这个点距离最远的点一定是树的直径中的一点

    然后在以这个点再跑一遍dfs 那么最长的一条链就是树的直径了

    用邻接表t了

    用vector又过了

    最近有点开始怀疑邻接表的性能有时其实是不如vetcor的

    注意的是本题用栈会爆

    附上扩栈语句

    #pragma comment(linker, "/STACK:102400000,102400000")

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<map>
    #include<stack>
    #include<algorithm>
    #include<vector>
    using namespace std;
    int st[200005];
    vector<int>ve[200005],ve2[200005];
    int dfn[200005];
    int low[200005];
    int belong[200005];
    int top=0;//栈顶
    int id=0;
    int num=0;//分量数
    int n,m;
    int MAX=0;//直径
    int p;
    void tarjan(int x,int last)
    {
        int flag=0;//定义第几次看到回溯父节点
        st[++top]=x;
        dfn[x]=low[x]=++id;
        for(int i=0; i<ve[x].size(); i++)
        {
            int temp=ve[x][i];
            if(temp==last&&flag==0)
            {
                flag=1;
                continue;
            }
            if(!dfn[temp])
            {
                tarjan(temp,x);
                low[x]=min(low[x],low[temp]);
            }
            else
            {
                low[x]=min(low[x],dfn[temp]);
            }
        }
        if(dfn[x]==low[x])//边双缩点
        {
            num++;
            while(st[top]!=x)
            {
                belong[st[top]]=num;
                top--;
            }
            belong[st[top]]=num;
            top--;
        }
        return ;
    }
    void suodian()
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<ve[i].size(); j++)
            {
                if(belong[i]!=belong[ve[i][j]])
                {
                    ve2[belong[i]].push_back(belong[ve[i][j]]);
                }
            }
        }
    }
    void dfs(int x,int step,int last)
    {
        //cout<<x<<endl;
        if(step>MAX) MAX=step,p=x;
        for(int i=0; i<ve2[x].size(); i++)
        {
            int temp;
            temp=ve2[x][i];
            if(temp!=last) dfs(temp,step+1,x);
        }
        return ;
    }
    void intal()
    {
        top=0;
        MAX=0;
        num=0;
        id=0;
        for(int i=1; i<=n; i++)
        {
            dfn[i]=0;
            ve[i].clear();
            ve2[i].clear();
        }
        return ;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            if(!n&&!m) return 0;
            intal();
            for(int i=1; i<=m; i++)
            {
                int temp1,temp2;
                scanf("%d%d",&temp1,&temp2);
                ve[temp1].push_back(temp2);
                ve[temp2].push_back(temp1);
            }
            tarjan(1,-1);
    //        for(int i=1; i<=n; i++)
    //            cout<<i<<"->"<<belong[i]<<endl;
            //cout<<"num="<<num<<endl;
            suodian();
            dfs(1,0,-1);
            //cout<<"p="<<p<<endl;
            MAX=0;
            dfs(p,0,-1);
            //cout<<"sum="<<sum<<"MAX="<<MAX<<endl;
            int ans=0;
            //ans=max(ans,sum-MAX);
            printf("%d
    ",num-1-MAX);
        }
    }
    
  • 相关阅读:
    2017-2018-1 20155232 《信息安全系统设计基础》第四周学习总结以及课上myod练习补充博客
    # 2017-2018-1 20155232 《信息安全系统设计基础》第三周学习总结
    # 2017-2018-1 20155232 《信息安全系统设计基础》第二周课堂实验
    2017-2018-1 20155232 《信息安全系统设计基础》第1周学习总结
    20155232 2016-2017-2《Java程序设计》课程总结
    20155232 实验五 网络编程与安全
    20155232 5月24日课堂时间提交补充
    20155232 实验四 Android程序设计
    信息安全系统设计基础第九周学习总结
    家庭作业6.32
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852275.html
Copyright © 2011-2022 走看看