HDU 4587 B - TWO NODES tarjan

…衆ロ難τιáo~ 提交于 2020-01-05 03:19:31

B - TWO NODES
Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87326#problem/B

Description

Suppose that G is an undirected graph, and the value of stab is defined as follows: 


Among the expression,G -i, -j is the remainder after removing node i, node j and all edges that are directly relevant to the previous two nodes. cntCompent is the number of connected components of X independently. 
Thus, given a certain undirected graph G, you are supposed to calculating the value of stab.
 

Input

The input will contain the description of several graphs. For each graph, the description consist of an integer N for the number of nodes, an integer M for the number of edges, and M pairs of integers for edges (3<=N,M<=5000). 
Please note that the endpoints of edge is marked in the range of [0,N-1], and input cases ends with EOF.

Output

For each graph in the input, you should output the value of stab.

Sample Input

4 5
0 1
1 2
2 3
3 0
0 2

Sample Output

HINT

 

题意

一个图,让你删除两个点之后,连通块最多有多少个

题解

枚举第一个点,然后跑tarjan求割点就好了

代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N=10010;
int dfn[N],low[N],pre[N],to[N],nxt[N],vis[N],sum[N],cnt,tm,ans,tot,ret,aim,n,m;

void makeedge(int a,int b)
{
    to[cnt]=a;nxt[cnt]=pre[b];pre[b]=cnt++;
    to[cnt]=b;nxt[cnt]=pre[a];pre[a]=cnt++;
    return ;
}

void dfs(int x,int fa)
{
    dfn[x]=tm;
    low[x]=tm++;
    vis[x]=1;
    sum[x]=0;
    for(int p=pre[x];p!=-1;p=nxt[p])
    {
        if(to[p]!=aim&&to[p]!=fa)
        {
            int y=to[p];
            if(!vis[y])
            {
                vis[y]=1;
                dfs(y,x);
                low[x]=min(low[y],low[x]);
                if(low[y]>=dfn[x]) sum[x]++;
            }
            else
            {
                low[x]=min(low[x],dfn[y]);
            }
        }
    }
    if(x==fa) sum[x]--;
    if(ans<sum[x]) ans=sum[x];
    return ;
}

void solve()
{
    ans=-1;tot=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        if(!vis[i]&&i!=aim)
        {
            tm=0;
            dfs(i,i);
            tot++;
        }
    if(ret<ans+tot+2) ret=ans+tot+2;
 //   cout<<ans<<" "<<tot<<" "<<ans+tot+2<<endl;
    return ;
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
    memset(pre,-1,sizeof(pre));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(vis,0,sizeof(vis));
    memset(sum,0,sizeof(sum));
    cnt=0;ans=0;tot=0;tm=0;ret=0;
    for(int i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        a++,b++;
        makeedge(a,b);
    }
    for(int i=1;i<=n;i++)
    {
        aim=i;
        solve();
    }
    printf("%d\n",ret-2);
    }
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!