1738

1738 - TWO NODES

时间限制: 10000 MS
内存限制: 65535 KB

问题描述

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(X)  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 consists of multiple cases.

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.

输出说明

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

输入样例

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

输出样例

2

来源

2013 ACM-ICPC China Nanjing Invitational Programming Contest
 
#include <iostream>
#include <stdio.h>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <map>
#include <stack>
#include <math.h>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#pragma comment(linker, "/STACK:10240000000000,10240000000000")
using namespace std;
typedef long long LL ;
const int Max_N=5008 ;
struct Edge{
   int v ;
   int next ;
};
Edge edge[Max_N*2] ;
int id  ,indx ;
int vec[Max_N] ,dfn[Max_N] ,low[Max_N] ;
bool visited[Max_N];
void add_edge(int u ,int v){
     edge[id].v=v ;
     edge[id].next=vec[u]  ;
     vec[u]=id++ ;
}
void init(){
    id=0 ;
    indx=0 ;
    memset(vec,-1,sizeof(vec)) ;
}
int ans ,root_son ;
int can_use[Max_N] ;

void dfs(int u ,bool is_root){
    dfn[u]=low[u]=++indx ;
    visited[u]=1 ;
    int child = 0 ;
    for(int e=vec[u];e!=-1;e=edge[e].next){
        int v=edge[e].v ;
        if(can_use[v]==0)
            continue ;
        if(!dfn[v]){
            dfs(v,0) ;
            if(is_root)
                root_son++ ;
            else{
                low[u]=Min(low[u],low[v]) ;
                if(low[v]>=dfn[u])
                     child++ ;
            }
        }
        else
            low[u]=Min(low[u],dfn[v]) ;
    }
    ans=Max(ans ,child+1) ;   //注意+1
}

int tarjan(int root){
     if(vec[root]==-1)    //块内就一个点的情况
        return 0 ;
     memset(dfn,0,sizeof(dfn)) ;
     ans=0 ; //删除当前块里面的某点产生的分量数
     root_son=0 ;
     dfs(root,1) ;
     ans=Max(ans,root_son) ;
     return ans ;
}

int main(){
    int N ,M ,u ,v ,ans ,child ,sum;
    while(scanf("%d%d",&N,&M)!=EOF){
        init() ;
        sum=0 ;
        while(M--){
            scanf("%d%d",&u,&v) ;
            add_edge(u,v) ;
            add_edge(v,u) ;
        }
        memset(can_use,1,sizeof(can_use)) ;
        for(int k=0;k<N;k++){
            can_use[k]=0 ;
            child=0 ;
            ans=0 ;
            memset(visited,0,sizeof(visited)) ;
            for(int i=0;i<N;i++){
                if(can_use[i]==0)
                     continue  ;
                if(!visited[i]){
                    child++ ;
                    ans=Max(ans,tarjan(i)) ;
                }
            }
            //cout<<child+ans-1<<endl ;   //原来就有1块
            int now=child+ans-1 ;
            sum=Max(sum,now) ;
            can_use[k]=1 ;
        }
        cout<<sum<<endl ;
    }
    return 0 ;
}
原文地址:https://www.cnblogs.com/liyangtianmen/p/3397703.html