• HDU4612 Warm up


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612

    题意:给定一个无向图,问加一条边后最少的桥数是多少。

    思路:找出边双连通分量后缩点成一棵树,然后我们要是加一条边使桥数最少,显然是去找树的直径,
    所以两边DFS去找树的直径即可,注意这里很坑,重边是不算桥的,所以要特殊处理,下面给出两种实现的代码。

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <map>
    #include <set>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define lson root<<1,l,mid
    #define rson root<<1|1,mid+1,r
    #define Key_Value ch[ch[root][1]][0]
    #define DBN1(a)           cerr<<#a<<"="<<(a)<<"
    "
    #define DBN2(a,b)         cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<"
    "
    #define DBN3(a,b,c)       cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"
    "
    #define DBN4(a,b,c,d)     cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"
    "
    #define DBN5(a,b,c,d,e)   cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<"
    "
    #define DBN6(a,b,c,d,e,f) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<", "<<#f<<"="<<(f)<<"
    "
    #define clr(a,x) memset(a,x,sizeof(a))
    using namespace std;
    typedef long long ll;
    const int maxn=200000+5;
    const int INF=0x3f3f3f3f;
    const int P=1000000007;
    const double PI=acos(-1.0);
    template<typename T>
    inline T read(T&x){
        x=0;int _f=0;char ch=getchar();
        while(ch<'0'||ch>'9')_f|=(ch=='-'),ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x=_f?-x:x;
    }
    struct Edge{
        int to;
        bool iscut;
        Edge(int _,bool __):to(_),iscut(__){}
    };
    int n,m,u,v,bcc_cnt,s,mx,dfs_clock,bccno[maxn],pre[maxn],low[maxn],dis[maxn];
    vector<int>G[maxn];
    vector<int>G2[maxn];
    vector<Edge>edges;
    void init(){
        bcc_cnt=dfs_clock=0;
        memset(pre,0,sizeof(pre));
        memset(bccno,0,sizeof(bccno));
        for (int i=1;i<=n;i++) G[i].clear(),G2[i].clear();
        edges.clear();
    }
    int dfs1(int u,int f){
        int lowu=pre[u]=++dfs_clock;
        for (int i=0;i<(int)G[u].size();i++){
            int v=edges[G[u][i]].to;
            if (!pre[v]){
                int lowv=dfs1(v,u);
                lowu=min(lowu,lowv);
                if (lowv>pre[u]) edges[G[u][i]].iscut=true,edges[G[u][i]^1].iscut=true;
            }
            else if (pre[v]<pre[u] && v!=f) lowu=min(lowu,pre[v]);
        }
        return low[u]=lowu;
    }
    void dfs2(int u){
        bccno[u]=bcc_cnt;
        for (int i=0;i<(int)G[u].size();i++){
            Edge &e=edges[G[u][i]];int v=e.to;
            if (!bccno[v] && !e.iscut) dfs2(v);//天然避开了重边的问题,因为有重边那么重边的iscut肯定是false肯定会被合并到边双连通分量里
        }
    }
    void find_bcc(){
        for (int i=1;i<=n;i++) if (!pre[i]) dfs1(i,-1);
        for (int i=1;i<=n;i++) if (!bccno[i]) bcc_cnt++,dfs2(i);
    }
    void dfs3(int u,int f,int dis){
        if (dis>mx){
            mx=dis;
            s=u;
        }
        for (int i=0;i<(int)G2[u].size();i++){
            int v=G2[u][i];
            if (v==f) continue;
            dfs3(v,u,dis+1);
        }
    }
    int main(){
        while (~scanf("%d%d",&n,&m)&&n+m){
            init();
            for (int i=1;i<=m;i++){
                read(u),read(v);
                edges.push_back(Edge(v,false));
                edges.push_back(Edge(u,false));
                int m=edges.size();
                G[u].push_back(m-2);
                G[v].push_back(m-1);
            }
            find_bcc();
            if (bcc_cnt==1){
                puts("0");
                continue;
            }
            for (int u=1;u<=n;u++){
                for (int i=0;i<(int)G[u].size();i++){
                    int v=edges[G[u][i]].to;
                    if (bccno[u]!=bccno[v]){
                        G2[bccno[u]].push_back(bccno[v]);
                    }
                }
            }
            mx=0;
            dfs3(1,-1,0);
            dfs3(s,-1,0);
            printf("%d
    ",bcc_cnt-mx-1);
        }
        return 0;
    }
    

      

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <map>
    #include <set>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define lson root<<1,l,mid
    #define rson root<<1|1,mid+1,r
    #define Key_Value ch[ch[root][1]][0]
    #define DBN1(a)           cerr<<#a<<"="<<(a)<<"
    "
    #define DBN2(a,b)         cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<"
    "
    #define DBN3(a,b,c)       cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"
    "
    #define DBN4(a,b,c,d)     cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"
    "
    #define DBN5(a,b,c,d,e)   cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<"
    "
    #define DBN6(a,b,c,d,e,f) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<", "<<#f<<"="<<(f)<<"
    "
    #define clr(a,x) memset(a,x,sizeof(a))
    using namespace std;
    typedef long long ll;
    const int maxn=200000+5;
    const int INF=0x3f3f3f3f;
    const int P=1000000007;
    const double PI=acos(-1.0);
    template<typename T>
    inline T read(T&x){
        x=0;int _f=0;char ch=getchar();
        while(ch<'0'||ch>'9')_f|=(ch=='-'),ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x=_f?-x:x;
    }
    int n,m,u,v,bcc_cnt,s,mx,dfs_clock,bccno[maxn],pre[maxn],low[maxn];
    vector<int>G[maxn];
    vector<int>G2[maxn];
    stack<int>S;
    void init(){
        bcc_cnt=dfs_clock=0;
        memset(pre,0,sizeof(pre));
        for (int i=1;i<=n;i++) G[i].clear(),G2[i].clear();
        while (!S.empty())S.pop();
    }
    int dfs1(int u,int f){
        int lowu=pre[u]=++dfs_clock,k=0;
        S.push(u);
        for (int i=0;i<(int)G[u].size();i++){
            int v=G[u][i];
            if (v==f && !k){//重边保证可以走
                k++;
                continue;
            }
            if (!pre[v]){
                int lowv=dfs1(v,u);
                lowu=min(lowu,lowv);
            }
            else if (pre[v]<pre[u]) lowu=min(lowu,pre[v]);
        }
        if (lowu==pre[u]){
            bcc_cnt++;
            for (;;){
                int v=S.top();S.pop();
                bccno[v]=bcc_cnt;
                if (v==u) break;
            }
        }
        return low[u]=lowu;
    }
    void find_bcc(){
        for (int i=1;i<=n;i++) if (!pre[i]) dfs1(i,-1);
    }
    void dfs2(int u,int f,int dis){
        if (dis>mx){
            mx=dis;
            s=u;
        }
        for (int i=0;i<(int)G2[u].size();i++){
            int v=G2[u][i];
            if (v==f) continue;
            dfs2(v,u,dis+1);
        }
    }
    int main(){
        while (~scanf("%d%d",&n,&m)&&n+m){
            init();
            for (int i=1;i<=m;i++){
                read(u),read(v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
            find_bcc();
            if (bcc_cnt==1){
                puts("0");
                continue;
            }
            for (int u=1;u<=n;u++){
                for (int i=0;i<(int)G[u].size();i++){
                    int v=G[u][i];
                    if (bccno[u]!=bccno[v]){
                        G2[bccno[u]].push_back(bccno[v]);
                    }
                }
            }
            mx=0;
            dfs2(1,-1,0);
            dfs2(s,-1,0);
            printf("%d
    ",bcc_cnt-mx-1);
        }
        return 0;
    }
    

      

  • 相关阅读:
    xml解析
    xml基础
    对象的深浅克隆
    批处理文件(bat)
    贪吃蛇逻辑代码
    排序算法
    tcp,第一个例子,客户端,服务端
    网络编程三要素
    装饰者模式
    工作中遇到的问题
  • 原文地址:https://www.cnblogs.com/cutemush/p/12682856.html
Copyright © 2020-2023  润新知