【割点】 HDU 4587 TWO NODES

来源:互联网 发布:java全排列 编辑:程序博客网 时间:2024/05/17 20:31

点击打开链接

去掉两个点后,连通图的个数

先枚举一个点,去掉该点,然后在对剩下的图DFS求去掉一个割点后连通图的个数

若没边时,DFS得到的是点的个数而没有去掉割点,所以需要 ans - 1 


#include <cstdio>#include <cstring>#include <cstdlib>#include <cctype>#include <climits>#include <iostream>#include <algorithm>using namespace std;#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1#include <queue>#define LL long longconst int MAXN = 10010;const int MAXM = 100010;struct Edge{    int to,next;    bool cut;}edge[MAXM];int head[MAXN],tot;int Low[MAXN],DFN[MAXN],Stack[MAXN];int Index,top;bool Instack[MAXN];bool cut[MAXN];int add_block[MAXN];//int bridge;void addedge(int u,int v){    edge[tot].to=v,edge[tot].next=head[u];edge[tot].cut=false;    head[u]=tot++;}void init(){    tot=0;memset(head,-1,sizeof(head));}void Tarjan(int u,int pre,int xxx){    int v;    Low[u]=DFN[u]=++Index;    Stack[top++]=u;    Instack[u]=true;    int son =0;    int pre_cnt=0;//congbian    for(int i=head[u];~i;i=edge[i].next)    {        v=edge[i].to;        if(xxx==v) continue;        if(v==pre&&pre_cnt==0){pre_cnt++;continue;}//congbian        if(!DFN[v])        {            son++;            Tarjan(v,u,xxx);            if(Low[u]>Low[v]) Low[u]=Low[v];            if(Low[v]>DFN[u]) {                bridge++;                edge[i].cut=true;                edge[i^1].cut=true;            }            if(u!=pre&&Low[v]>=DFN[u])            {                cut[u]=true;                add_block[u]++;            }        }        else if(Low[u]>DFN[v])            Low[u]=DFN[v];    }    if(u==pre&&son>1) cut[u]=true;    if(u==pre) add_block[u]=son-1;    Instack[u]=false;    top--;}int solve(int N,int x)//xianshan x;{    memset(DFN,0,sizeof(DFN));    memset(Instack,0,sizeof(Instack));    memset(add_block,0,sizeof(add_block));    memset(cut,false,sizeof(cut));    Index=top=0;    int cnt=0;//    for(int i=1;i<=N;i++)        if(!DFN[i]&&i!=x)        {            Tarjan(i,i,x);            cnt++;        }    int ans=0;    for(int i=1;i<=N;i++)    {        ans=max(ans,cnt+add_block[i]);    }//    printf("%d:%d\n",x,ans);    if(N-1==cnt)        ans--;    return ans;}int main(){    int n,m,a,b;    while(cin>>n>>m)    {        init();        for(int i=1;i<=m;i++)        {            scanf("%d%d",&a,&b);            a++,b++;            addedge(a,b);            addedge(b,a);        }        int ans=0;       // ans=solve(n,0);        for(int i=1;i<=n;i++)        {            ans=max(ans,solve(n,i));        }        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击