zoukankan      html  css  js  c++  java
  • POJ3177Redundant Paths

    边双连通分量

    这题的数据量比题目写的小,这题还需要判重,

    2个确定的点之间的任何边都算same path,唔,不知道为什么,很弱看不懂题目。。。。

    所以要先去重边,然后dfs求出桥,再dfs求出边双连通分量(只要不经过桥就行了)

    问加多少条边使得任意两点都有两条不同边的路,就是求一个双连通分量

    所以求出边双连通分量,然后缩点形成新图,

    新图上度数为1的节点(即叶节点)数目为ans

    (ans+1)/2 即为答案

    View Code 
    
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <stack>
    #include <map>
    using namespace std;
    #define MAXN 1000+5
    #define MAXM 10050*10
    int F,R;
    int e;
    vector<int>G[MAXN],P[MAXN];
    int dfs_clock,bcc_cnt;
    int pre[MAXN];
    int first2[MAXN];
    int T[MAXN];
    int M[MAXN][MAXN];
    int dfs1(int u,int fa)
    {
        int lowu=pre[u]=++dfs_clock;
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(!pre[v])
            {
                int lowv=dfs1(v,u);
                lowu=min(lowu,lowv);
                if(lowv>pre[u])
                {
                    P[v].push_back(u);
                    P[u].push_back(v);
                }
            }
            else if(pre[v]<pre[u]&&v!=fa)
            {
                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=G[u][i];
            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);
            }
    }
    int ans[MAXN];
    int main()
    {
      //  freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&F,&R))
        {
            int a,b;
            memset(M,0,sizeof(M));
            for(int i=0;i<MAXN;i++){
                G[i].clear();
                P[i].clear();
            }
            for(int i=0;i<R;i++)
            {
                scanf("%d%d",&a,&b);
                if(M[a][b]==1)continue;
                M[a][b]=M[b][a]=1;
                G[a].push_back(b);
                G[b].push_back(a);
            }
            find_bcc(F);
            memset(ans,0,sizeof(ans));
            for(int i=1;i<=F;i++)
                for(int j=0;j<G[i].size();j++)
                {
                    int v=G[i][j];
                    if(T[i]!=T[v])
                        ans[T[i]]++;
                }
            int re=0;
            for(int i=1;i<=bcc_cnt;i++)
                if(ans[i]==1)
                    re++;
            printf("%d\n",(re+1)/2);
        }
    }
  • 相关阅读:
    golang 多个worker正常关闭的示例
    golang调试工具Delve
    Golang & GitLab-CI 详细实例步骤
    [git] 能在关键时刻救命的git指令
    高效实时数据排行榜实现
    [Golang] 编译程序时打上git提交信息标记
    [Golang] 开源一个帧同步服务器
    Golang etcd服务注册与发现
    Golang pprof详解
    shell 递归枚举文件并操作
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2862069.html
Copyright © 2011-2022 走看看