• hdu-4612-Warm up(边双连通分量--有重边)


    题意:有N 个点,M条边,加一条边,求割边最少。(有重边)

    分析:先求双连通分量,缩点形成一个生成树,然后求这个的直径,割边-直径即是答案

    因为有的图上可能有重边,这样不好处理。我们记录每条边的标号(一条无向边拆成的两条有向边标号相同)这样就能限制不走一样的边而能走重边!

    // File Name: 1002.cpp
    // Author: Zlbing
    // Created Time: 2013年08月02日 星期五 18时16分10秒
    #pragma comment(linker,"/STACK:102400000,102400000")
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=2e5+100;
    
    int n,m;
    struct Edge{
        int u,v;
        Edge(){}
        Edge(int a,int b){
            u=a;
            v=b;
        }
    };
    vector<Edge> edges;
    vector<int> G[MAXN];
    vector<int> P[MAXN];
    int dfs_clock,bcc_cnt;
    int pre[MAXN];
    int T[MAXN];
    //fa为u的父亲边
    //这样标识就可以走重边而不能走父亲边
    int dfs1(int u,int fa)
    {
        int lowu=pre[u]=++dfs_clock;
        for(int i=0;i<G[u].size();i++)
        {
            int mm=G[u][i];
            int v=edges[mm].v;
            if(fa==(mm^1))continue;
            if(!pre[v])
            {
                int lowv=dfs1(v,mm);
                lowu=min(lowu,lowv);
                if(lowv>pre[u])
                {
                    P[v].push_back(u);
                    P[u].push_back(v);
                }
            }
            else if(pre[v]<pre[u])
            {
                lowu=min(pre[v],lowu);
            }
        }
        return lowu;
    }
    void dfs2(int u,int fa)
    {
        T[u]=bcc_cnt;
        for(int i=0;i<G[u].size();i++)
        {
            int v=edges[G[u][i]].v;
            bool f=true;
            for(int j=0;j<P[u].size();j++)
            {
                int vv=P[u][j];
                if(v==vv)
                {
                    f=false;break;
                }
            }
            if(!f||T[v])continue;
            dfs2(v,u);
        }
    }
    void find_bcc(int n)
    {
         dfs_clock=0,bcc_cnt=0;
        memset(pre,0,sizeof(pre));
        memset(T,0,sizeof(T));
        for(int i=1;i<=n;i++)
            if(!pre[i])
                dfs1(i,-1);
        for(int i=1;i<=n;i++)
            if(!T[i])
            {
                bcc_cnt++;
                dfs2(i,-1);
            }
    }
    vector<int> GG[MAXN];
    int d[MAXN];
    void dfs(int u,int dep)
    {
        d[u]=dep;
        for(int i=0;i<GG[u].size();i++)
        {
            int v=GG[u][i];
            if(!d[v])
            {
                dfs(v,dep+1);
            }
        }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            if(n+m==0)break;
            REP(i,0,n){
                G[i].clear();
                P[i].clear();
            }
            edges.clear();
            int a,b;
            REP(i,1,m)
            {
                scanf("%d%d",&a,&b);
                Edge e;
                e=Edge(a,b);
                edges.push_back(e);
                e=Edge(b,a);
                edges.push_back(e);
                int mm=edges.size();
                G[a].push_back(mm-2);
                G[b].push_back(mm-1);
            }
            find_bcc(n);
            REP(i,0,n)
            {
                GG[i].clear();
            }
            /*
            for(int i=1;i<=n;i++)
            {
                printf("T[%d]=%d
    ",i,T[i]);
            }
            */
            for(int i=1;i<=n;i++)
            {
                for(int j=0;j<P[i].size();j++)
                {
                    int v=P[i][j];
                    if(T[i]!=T[v])
                    {
                    //    printf("u=%d v=%d
    ",T[i],T[v]);
                        GG[T[i]].push_back(T[v]);
                    }
                }
            }
            CL(d,0);
            dfs(1,1);
            int maxn=0;
            int flag=0;
            for(int i=1;i<=bcc_cnt;i++)
            {
                if(d[i]>maxn)
                {
                    maxn=d[i];
                    flag=i;
                }
            }
            CL(d,0);
            dfs(flag,1);
            maxn=0;
            for(int i=1;i<=bcc_cnt;i++)
            {
                if(d[i]>maxn)
                    maxn=d[i];
            }
        //    printf("bcc_cnt=%d maxn=%d
    ",bcc_cnt,maxn);
            cout<<bcc_cnt-maxn<<endl;
        }
        return 0;
    }
  • 相关阅读:
    【SpringBoot】 理解SpringBoot的启动原理
    【SpringBoot】SpringBoot的基础,全面理解bean的生命周期
    【转】 Linux 命令解释(Linux基础二)
    【转】 Linux 的目录详解 (Linux基础一)
    【SpringBoot】 一种解决接口返回慢的方式
    【Jmeter基础】 Linux上运行Jmeter
    【SpingBoot】 测试如何使用SpringBoot搭建一个简单后台1
    单例模式@Singleton在测试中的运用
    性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)
    Spring5源码分析(007)——IoC篇之加载BeanDefinition总览
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3236092.html
Copyright © 2020-2023  润新知