hdu-3671-tarjin/割点方案

http://acm.hdu.edu.cn/showproblem.php?pid=3671

给出一幅无向图,询问有多少种移除点对的方案使得剩下的连通分量个数大于1.

和上一题差不多的思路直接做n次tarjin即可。

 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=1010;
 9 vector<int>g[maxn];
10 int dfn[maxn],low[maxn],sub[maxn],root,sum,ban;
11 bool vis[maxn];
12 void dfs(int u){
13     dfn[u]=low[u]=sum++;
14     vis[u]=1;
15     int son=0;
16     for(int i=0;i<g[u].size();++i){
17         int v=g[u][i];
18         if(v==ban) continue;
19         if(vis[v]){
20             low[u]=min(low[u],dfn[v]);
21         }
22         else{
23             dfs(v);
24             if(u==root)son++;
25             else{
26                 if(low[v]>=dfn[u])sub[u]++;
27             }
28             low[u]=min(low[u],low[v]);
29         }
30     }
31     if(u==root)sub[u]=son;
32     else sub[u]++;
33 }
34 int main(){
35     int n,m,cas=0,i,j,u,v;
36     while(scanf("%d%d",&n,&m)==2){
37         if(n==0&&m==0)break;
38         for(i=1;i<=n;++i)g[i].clear();
39         while(m--){
40             scanf("%d%d",&u,&v);
41             g[u].pb(v);
42             g[v].pb(u);
43         }
44         int ans=0;
45         for(i=1;i<=n;++i){
46             int p=0;
47             ban=i,sum=0;
48             memset(vis,0,sizeof(vis));
49             memset(sub,0,sizeof(sub));
50             for(j=1;j<=n;++j){
51                 if(j==ban || vis[j]) continue;
52                 root=j;
53                 p++;
54                 dfs(j);
55             }
56             //cout<<"p="<<p<<endl;
57             for(j=i+1;j<=n;++j){
58                 if(sub[j]+p-1>=2)ans++;
59             }    
60         }
61         printf("Case %d: %d
",++cas,ans);
62     }
63     return 0;
64 }
原文地址:https://www.cnblogs.com/zzqc/p/10063353.html