TWO NODES

Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 450    Accepted Submission(s): 86


Problem 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
2

题意:在一个无向图中任意去掉两个点,问我们最多剩余几个连通块。

解题思路:注意到n,m并不大,先枚举第一个删除的点,之后在O(m)的时间内求出最佳的割点。

我的代码:

#include <stdio.h>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int MAXN = 5005;
int n, m;
struct Edge{
    int u, v, nxt;
}   e[MAXN << 1];
int pnt[MAXN],fa[MAXN];
int num[MAXN], low[MAXN];
int ans,totalEdge,gtot,stamp;
void addEdge(int x, int y){
    int i = totalEdge++;
    e[i].u = x;
    e[i].v = y;
    e[i].nxt = pnt[x];
    pnt[x] = i;
}
int findpa(int x){
    if (fa[x] == x) return x;
    return fa[x] = findpa(fa[x]);
}
void dfs(int x, int fa){
 int i,j,tot;
    tot=0;
    num[x]=low[x]=stamp++;
    for (i=pnt[x];i>=0;i=e[i].nxt)
 {
        int y=e[i].v;
        if (y==fa) continue;
        if (num[y]==-1)
     {
            dfs(y, x);
            low[x]=min(low[x],low[y]);
            if (low[y]>=num[x]){
                tot+=1;
            }
        }
        else
    if(num[y]>=0) low[x]=min(low[x],num[y]);
    }
    ans=max(ans,gtot-1+tot+(fa!=-1));
}
void gao(int x){
 int i,j,k;
    for(i=0;i<n;i++) fa[i]=i;
    gtot=n-1;
    for(i=0;i<totalEdge;i++)
 {
        j=e[i].u; k=e[i].v;
        if(j==x||k==x) continue;
        fa[j]=findpa(j); fa[k]=findpa(k);
        if(fa[j]!= fa[k])
     {
            fa[fa[j]]=fa[k];
            gtot-=1;
        }
    }
    for(i=0;i<n;i++) num[i]=-1;
    num[x]=-2;
    stamp=0;
    for(i=0;i<n;i++)
        if(num[i]==-1) dfs(i,-1);
}
int main(){
 int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
       ans=0;
         for(i=0;i<n;i++) pnt[i]=-1;
         totalEdge=0;
         for(i=0;i<m;i++)
         {
           int x,y;
           scanf("%d%d",&x,&y);
           addEdge(x,y); addEdge(y,x);
         }
         for(i=0;i<n;i++) gao(i);
         printf("%d\n",ans);
    }
    return 0;
}