HDU - 4587

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liufengwei1/article/details/83106604

枚举去掉一个点,再用一个tarjan 求出去掉第二个点最多能分成多少块?

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=5e3+5;
int n,m,idx;
int l[maxn],r[maxn];
int dfn[maxn],low[maxn],sub[maxn];
int root,chd;
vector<int>G[maxn];
inline void dfs(int u,int fa){
    low[u]=dfn[u]=++idx;
    for(int i=0;i<G[u].size();++i){
        int v=G[u][i];
        if(!dfn[v]){
            dfs(v,u);
            low[u]=min(low[u],low[v]);
            if(u==root)++chd;
            else if(low[v]>=dfn[u])++sub[u];
        }else if(v!=fa)low[u]=min(low[u],dfn[v]);
    }
}
inline int work(int tar){
    for(int i=0;i<n;++i)G[i].clear();
    for(int i=0;i<m;++i)
        if(l[i]!=tar&&r[i]!=tar){
            G[l[i]].push_back(r[i]);
            G[r[i]].push_back(l[i]);
        }
    memset(dfn,0,sizeof(int)*n);
    memset(low,0,sizeof(int)*n);
    memset(sub,0,sizeof(int)*n);
    int cnt=0;
    for(int i=0;i<n;++i)
        if(!dfn[i]){
            ++cnt;
            idx=0;
            root=i;chd=0;
            dfs(i,-1);
            sub[i]=chd-1;
        }
    cnt--;
    //cout<<cnt<<endl;
    int res=0;
    for(int i=0;i<n;++i)res=max(res,cnt+sub[i]);
    res=max(res,0);
    return res;
}
int main()
{
//	freopen("T.in","r",stdin);
//	freopen("T.out","w",stdout);
    while(~scanf("%d%d",&n,&m)){
        for(int i=0;i<m;++i){
            scanf("%d%d",l+i,r+i);
        }
        int ans=0;
        for(int i=0;i<n;++i)
            ans=max(ans,work(i));
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/83106604
hdu
今日推荐