poj2117-tarjin求割点

http://poj.org/problem?id=2117

求移除一个点以及与它相邻边后,剩下的图中最大的联通子图的数量是多少。

跑一遍tarjin统计下拆除某个点剩下的子图数量即可。注意给出的图不一定时联通的,所以要加上(sum-1)。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cstring>
 5 using namespace std; 
 6 #define LL long long 
 7 #define pb push_back
 8 const int maxn=10010;
 9 vector<int>g[maxn];
10 int dfn[maxn],low[maxn],sub[maxn],root,sum;
11 bool vis[maxn];
12 void dfs(int u){
13     vis[u]=1;
14     dfn[u]=low[u]=sum++;
15     int son=0;
16     for(int i=0;i<g[u].size();++i){
17         int v=g[u][i];
18         if(vis[v]){
19             low[u]=min(low[u],dfn[v]);
20         }
21         else{
22             dfs(v);
23             if(u==root)son++;
24             else{
25                 if(low[v]>=dfn[u])sub[u]++;
26             }
27             low[u]=min(low[u],low[v]);
28         }
29     }
30     if(u==root)sub[u]=son;
31     else{
32         sub[u]++;
33     }
34 }
35 int main(){
36     int n,m,i,u,v;
37     while(scanf("%d%d",&n,&m)==2&&(n||m)){
38         for(i=0;i<n;++i){
39             g[i].clear();
40             sub[i]=vis[i]=0;
41         }sum=0;
42         while(m--){
43             scanf("%d%d",&u,&v);
44             g[u].pb(v);
45             g[v].pb(u);
46         }
47         int p=0,ans=0;
48         for(i=0;i<n;++i){
49             if(!vis[i]){
50                 p++;
51                 root=i;
52                 dfs(i);
53             }
54         }
55         for(i=0;i<n;++i){
56             ans=max(ans,sub[i]+p-1);
57         }
58         cout<<ans<<endl;
59     } 
60     return 0;
61 }
原文地址:https://www.cnblogs.com/zzqc/p/10062965.html