• NJUST1738 TWO NODES(割点)


    题意:求除去任意两点及这两点所连的边的连通分量最大

    分析:枚举一点,除去这一点形成了一个新图,然后求割点,因为另外一点肯定是割点,不然无法使连通分量最大!然后计算除去割点的连通分量,最后求最大值即可!

    // File Name: test.cpp
    // Author: Zlbing
    // Created Time: 2013/5/14 8:23:10
    
    #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--)
    #define MAXN 5000+100
    vector<int> G[MAXN];
    int pre[MAXN];
    int dfs_clock,bcc_cnt;
    struct Edge{
        int u,v;
    };
    vector<Edge> edges;
    int ans=0;
    int cnt;
    int n,m;
    int f[MAXN];
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    int dfs(int u,int fa,int a)
    {
       int lowu=pre[u]=++dfs_clock;
       int child=0;
      // printf("u=%d fa==%d \n",u,fa);
      int cc=G[u].size();
       for(int i=0;i<cc;i++)
       {
           int mm=G[u][i];
           int v=edges[mm].v;
           if(v==a)continue;
               if(!pre[v])
               {
                   int lowv=dfs(v,u,a);
                    lowu=min(lowu,lowv);
                   if(lowv>=pre[u])
                   {
            //       printf("v==%d\n",v);
                       child++;
                   }
               }
               else if(pre[v]<pre[u]&&v!=fa)
               {
                   lowu=min(pre[v],lowu);
               }
       }
       ans=max(ans,cnt-1+child+(fa!=-1));
       return lowu;
    }
    void find_bcc(int N,int a)
    {
    
        memset(pre,0,sizeof(pre));
        dfs_clock=0;
        bcc_cnt=0;
        cnt=N-1;
        int mm=edges.size();
        for(int i=0;i<N;i++)f[i]=i;
        for(int i=0;i<mm;i++)
        {
            int u=edges[i].u;
            int v=edges[i].v;
            if(u==a||v==a)continue;
            int fu=find(u);
            int fv=find(v);
            //printf("u==%d fu==%d v==%d fv==%d\n",u,fu,v,fv);
            if(fu!=fv)
            {
                cnt--;
                f[f[u]]=f[v];
            }
        }
        //printf("a==%d cnt==%d\n",a,cnt);
        for(int i=0;i<N;i++)
            if(!pre[i]&&i!=a)
                dfs(i,-1,a);
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            edges.clear();
            REP(i,0,n){
                G[i].clear();
            }
            int a,b;
            REP(i,1,m)
            {
                scanf("%d%d",&a,&b);
                if(a==b)continue;
                edges.push_back((Edge){a,b});
                edges.push_back((Edge){b,a});
                int mm=edges.size();
                G[a].push_back(mm-2);
                G[b].push_back(mm-1);
            }
            ans=0;
            for(int i=0;i<n;i++)
            {
                find_bcc(n,i);
            }
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    [APIO2016]划艇
    C# 循环的判断会进来几次
    C# 性能分析 反射 VS 配置文件 VS 预编译
    C# 性能分析 反射 VS 配置文件 VS 预编译
    AutoHotKey 用打码的快捷键
    AutoHotKey 用打码的快捷键
    C# 通过编程的方法在桌面创建回收站快捷方式
    C# 通过编程的方法在桌面创建回收站快捷方式
    C# 条件编译
    C# 条件编译
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3081319.html
Copyright © 2020-2023  润新知