hdu 3671无向图割点
感想:在做题的时候如果能够规划好,按自己的规划写代码bug出现的几率会少很多。 本来以为这道题会消耗我很长时间,结果很快就过了。
题意: 给出一个无向图,现在可以去点两个点想让剩下的图不再连通,问一共有多少种情况。
思路: 我的做法是枚举一个去掉的点,
如果剩下的图分成3部分(或大于三部分), 那么答案就要加n-1。
如果分成两部分,那么如果两部分的点的个数都不为1,那么结果要加n-1。
如果有一个为1,那么要加n-2,如果都为1,那么不加
如果剩下一部分,就按无向图求割点的方法求出。具体求法是这样
如果是根节点那么至少有两个子节点, 如果是其他点那么至少有一个子节点的low[v]>=lp[u]
AC代码:
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int N = 1050, M = 21000; 8 struct EDGE 9 { 10 int u, v, next; 11 }edge[M]; 12 13 int num, head[N], low[N], lp[N], step; 14 int n, m, ans=0, f, root; 15 16 void add(int u, int v) 17 { 18 edge[num].u = u; 19 edge[num].v = v; 20 edge[num].next = head[u]; 21 head[u] = num++; 22 } 23 24 void init() 25 { 26 num = 0; 27 memset(head, -1, sizeof(head)); 28 int u, v; 29 for(int i=0; i<m; i++) 30 { 31 scanf("%d%d", &u, &v); 32 add(u, v); 33 add(v, u); 34 } 35 } 36 37 int tarjan(int u) 38 { 39 lp[u] = low[u] = ++step; 40 int tp = 0,v, cc=1; 41 bool flag = 0; 42 for(int i = head[u];i != -1;i = edge[i].next) 43 { 44 v = edge[i].v; 45 if(v == f) continue; 46 if(!lp[v]) 47 { 48 cc++; 49 tp++; 50 tarjan(v); 51 low[u] = min(low[u],low[v]); 52 if(u != root&&lp[u] <= low[v]) 53 flag = 1; 54 } 55 else low[u] = min(low[u],lp[v]); 56 } 57 if(u == root && tp > 1) 58 flag = 1; 59 if(flag) ans++; 60 return cc; 61 } 62 63 64 void solve() 65 { 66 int result = 0; 67 int now, path[N] = {0}; 68 for(int i=1; i<=n; i++) 69 { 70 memset(low, 0, sizeof(low)); 71 memset(lp, 0, sizeof(lp)); 72 step = 1; 73 now = ans = 0; 74 f = i; 75 for(int j=1; j<=n; j++) 76 { 77 if(!lp[j] && j!=i) 78 { 79 root = j; 80 path[++now] = tarjan(j); 81 } 82 } 83 if(now > 2) result += n-1; 84 else if(now == 2) 85 { 86 sort(path+1, path+3); 87 if(path[1] == 1) 88 { 89 if(path[2] != 1) 90 result += n-2; 91 } 92 else result += n-1; 93 } 94 else result += ans; 95 } 96 printf("%d\n", result/2); 97 } 98 99 int main() 100 { 101 int t=0; 102 while(scanf("%d%d", &n, &m) != EOF) 103 { 104 if(n==0 && m==0) 105 break; 106 init(); 107 t++; 108 printf("Case %d: ", t); 109 solve(); 110 } 111 return 0; 112 }


浙公网安备 33010602011771号