NJUST-1738 - 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;
}

 

posted @ 2013-05-16 10:34  z.arbitrary  阅读(271)  评论(0)    收藏  举报