2013 南京理工大学邀请赛B题

思路:

每次枚举删除一个点,然后对剩下的点求出关键点,判断删除哪个关键点获得的连通分支数最大。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#define Maxn 5100
#define Maxm 50100
#define inf 0x7fffffff
using namespace std;
map<int,int> p[Maxn];
int Index[Maxn],dfn[Maxn],low[Maxn],vi[Maxn],compent[Maxn],e,n,lab,Max=0;
struct Edge{
    int from,to,next;
}edge[Maxm];
inline int min(int a,int b)
{
    return a<b?a:b;
}
inline int max(int a,int b)
{
    return a>b?a:b;
}
void init()
{
    memset(Index,-1,sizeof(Index));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(vi,0,sizeof(vi));
    memset(compent,0,sizeof(compent));
    for(int i=0;i<=n;i++)
        p[i].clear();
    e=lab=Max=0;
}
void Init()
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(vi,0,sizeof(vi));
    memset(compent,0,sizeof(compent));
    lab=Max=0;
}
void addedge(int from,int to)
{
    edge[e].from=from;
    edge[e].to=to;
    edge[e].next=Index[from];
    Index[from]=e++;
}
void dfs(int u,int farther)
{
    dfn[u]=low[u]=++lab;
    int i,temp;
    for(i=Index[u];i!=-1;i=edge[i].next)
    {
        temp=edge[i].to;
        if(!vi[temp])
        {
            if(!dfn[temp])
            {
                dfs(temp,u);
                if(low[temp]>=dfn[u])
                {
                    compent[u]++;
                    //cout<<u<<" * "<<compent[u]<<" "<<low[temp]<<" "<<temp<<endl;
                    Max=max(Max,compent[u]);
                }
                low[u]=min(low[u],low[temp]);
            }
            if(temp!=farther)
                low[u]=min(low[u],dfn[temp]);
        }
    }
}
int main()
{
    int i,j,m,a,b;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            a++;
            b++;
            if(!p[a][b])
            {
            addedge(a,b);
            addedge(b,a);
            p[a][b]=p[b][a];
            }
        }
        int num=0;
        int v;
        int ans=0;
        int flag=1;
        for(i=1;i<=n;i++)
        {
            Init();
            vi[i]=1;
            num=0;
            flag=1;
            for(j=1;j<=n;j++)
            {
                if(!vi[j]&&!dfn[j])
                {
                    compent[j]=-1;
                    dfn[j]=low[j]=++lab;
                    num++;
                    
                    for(int k=Index[j];k!=-1;k=edge[k].next)
                    {
                        v=edge[k].to;
                        if(!dfn[v]&&!vi[v])
                        {
                            flag=0;
                            compent[j]++;
                            Max=max(Max,compent[j]);
                            dfs(v,j);
                        }
                    }
                }
            }
            if(flag)
                num--;
            vi[i]=0;
            ans=max(ans,num+Max);
            //cout<<num<<" "<<Max<<endl;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2013-07-21 17:09  fangguo  阅读(156)  评论(0编辑  收藏  举报