hdu 4587(割点变形)

南京邀请赛B题

题意:一张无向图问你去除两个点最多能有多少个连通分支。

思路:由于是两个点所以我们先枚举删除死一个点再根据割点性质求出,连通分支个数。注意当所有连通分支都只有一个点的时候删除一个点就相当于删除一个联通分支。

代码如下:

 1 /**************************************************
 2  * Author     : xiaohao Z
 3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
 4  * Last modified : 2014-02-12 17:39
 5  * Filename     : hdu_4587.cpp
 6  * Description     : 
 7  * ************************************************/
 8 
 9 #include <iostream>
10 #include <cstdio>
11 #include <cstring>
12 #include <cstdlib>
13 #include <cmath>
14 #include <algorithm>
15 #include <queue>
16 #include <stack>
17 #include <vector>
18 #include <set>
19 #include <map>
20 #define MP(a, b) make_pair(a, b)
21 #define PB(a) push_back(a)
22 
23 using namespace std;
24 typedef long long ll;
25 typedef pair<int, int> pii;
26 typedef pair<unsigned int,unsigned int> puu;
27 typedef pair<int, double> pid;
28 typedef pair<ll, int> pli;
29 typedef pair<int, ll> pil;
30 
31 const int INF = 0x3f3f3f3f;
32 const double eps = 1E-6;
33 const int LEN = 5010;
34 vector<int> Map[LEN];
35 int dclock, cut[LEN], low[LEN], dfn[LEN], n, m, dv, ret, tcnt;
36 
37 void init(){
38     dclock = 1;
39     memset(dfn, -1, sizeof dfn);
40     memset(cut, 0, sizeof cut);
41 }
42 
43 void dfs(int u, int fa){
44     int son = 0;
45     dfn[u] = low[u] = dclock ++;
46     tcnt ++;
47     for(int i = 0; i < Map[u].size(); i ++){
48         int v = Map[u][i];
49         if(v == dv) continue;
50         if(dfn[v]<0){
51             dfs(v, u);
52             son ++;
53             low[u] = min(low[u], low[v]);
54             if((fa < 0 && son > 1) || (fa >= 0 && low[v] >= dfn[u])) {
55                 cut[u] ++;
56                 ret = max(ret, cut[u]);
57             }
58         }else if(low[u] > low[v] && v != fa) low[u] = min(low[u], dfn[v]);
59     }
60 }
61 
62 
63 int main()
64 {
65 //    freopen("in.txt", "r", stdin);
66 
67     int a, b;
68     while(scanf("%d%d", &n, &m)!=EOF){
69         for(int i=0; i<LEN; i++) Map[i].clear();
70         for(int i=0; i<m; i++){
71             scanf("%d%d", &a, &b);
72             Map[a].PB(b);
73             Map[b].PB(a);
74         }
75         int ans, maxans = 0;
76         for(int i=0; i<n; i++){
77              dv = i;
78              ans = 0;
79              init();
80              int f = 1, blo = 0;
81              for(int j=0; j<n; j++) 
82                  if(dfn[j] < 0 && i!=j){
83                     ret = tcnt = 0;
84                     dfs(j, -1);
85                     if(tcnt > 1) f = 0;
86                     blo ++;
87                 //    if(!ret) ret = 1;
88                     ans = max(ans, ret);
89                  }
90              if(f) ans --;
91              maxans = max(blo + ans, maxans);
92         }    
93         printf("%d
", maxans);
94     }
95     return 0;
96 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3546548.html