zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    WebApp匯入資料之對話框實現
    JSON學習
    [JSON]jQuery的parseJSON()函數使用
    DataTable.Merge()一次應用
    WebApp匯入資料之From Excel
    含有HTML碼的欄位寫入資料庫處理方法
    访问Webservice错误
    ASP.NET整合應用實例後端Services合作
    强直性脊柱炎活动指数(ASDAS)在日常诊疗种评估生物制剂治疗患者的应用-来自葡萄牙登记系统风湿病患者
    脊柱炎症水平在疾病活动度高低不等的脊柱关节炎患者中表现相似-来自一项群体研究结果
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3236092.html
Copyright © 2011-2022 走看看