POJ3177 Redundant Paths

给定一个无向图,求最少需要多少边可以让这个无向图里两两点之间都有两条路可以走。 
先tarjan算法进行缩点,得到一颗无向树 
对于无向树中非叶子结点,只要叶子结点连通了,就都有两条路可以走 
所以变成了需要多少条边可以把所以叶子结点连通 
当叶子结点是奇数时 答案就是ans =(ans)/ 2 + 1 
当叶子结点是偶数时 答案就是ans =(ans)/ 2 
所以ans = (ans + 1)/ 2

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 
  5 using namespace std;
  6 
  7 int n, m, tol, cnt, top;
  8 int stacksize;
  9 const int maxn = 5005;
 10 const int maxm = 10000;
 11 
 12 struct Node{
 13     int u;
 14     int v;
 15     int next;
 16 };
 17 Node node[maxm * 2];
 18 int head[maxn];
 19 int stack[maxn];
 20 int dfn[maxn];
 21 int low[maxn];
 22 int degree[maxn]; 
 23 int fath[maxn];
 24 bool maps[maxn][maxn];
 25 int point[maxn];
 26 
 27 void init() {
 28     top = tol = cnt = stacksize = 0;
 29     memset(dfn, 0, sizeof(dfn));
 30     memset(low, 0, sizeof(low)); 
 31     memset(node, 0, sizeof(node));
 32     memset(fath, 0, sizeof(fath));
 33     memset(head, -1, sizeof(head));
 34     memset(stack, 0, sizeof(stack));
 35     memset(point, 0, sizeof(point));
 36     memset(degree, 0, sizeof(degree));
 37     memset(maps, false, sizeof(maps));
 38 }
 39 
 40 void addnode(int u, int v) {
 41     node[tol].u = u;
 42     node[tol].v = v;
 43     node[tol].next = head[u];
 44     head[u] = tol++;
 45 }
 46 
 47 void dfs(int u, int fa) {
 48     int v;
 49     stack[stacksize++] = u;
 50     fath[u] = fa;
 51     dfn[u] = low[u] = ++cnt;
 52     for(int i=head[u]; i!=-1; i=node[i].next) {
 53         v = node[i].v;
 54         if(!dfn[v]){
 55             dfs(v, u);
 56             low[u] = min(low[u], low[v]);
 57         } else if(v != fa) {
 58             low[u] = min(low[u], dfn[v]);
 59         }
 60     }
 61     if(dfn[u] == low[u]) {
 62         top++; 
 63         do{
 64             v = stack[--stacksize];
 65             point[v] = top;
 66         } while(v != u);
 67     }
 68 }
 69 
 70 void tarjan() {
 71     for(int u=1; u<=n; u++) {
 72         if(!dfn[u]) {
 73             dfs(u, u);
 74         }
 75     }
 76 }
 77 
 78 void getdegree() {
 79     for(int u=1; u<=n; u++) {
 80         for(int i=head[u]; i!=-1; i=node[i].next) {
 81             int v = node[i].v;
 82             if(point[u] != point[v] && v != u) {
 83                 degree[point[u]]++;
 84             }
 85         }
 86     }
 87     int ans = 0;
 88     for(int i=1; i<=top; i++) {
 89         if(degree[i] == 1) {
 90             ans++;
 91         }
 92     }
 93     printf("%d\n", (ans+1)/2);
 94 }
 95 
 96 int main() {
 97     while(scanf("%d%d",&n, &m) != EOF) {
 98         init();
 99         for(int i=1; i<=m; i++) {
100             int u, v;
101             scanf("%d%d",&u, &v);
102             if(maps[u][v])
103                 continue;
104             maps[u][v] = maps[v][u] = true;
105             addnode(u, v);
106             addnode(v, u);
107         }
108         tarjan();
109         getdegree();
110     }
111     return 0;
112 }
View Code

猜你喜欢

转载自www.cnblogs.com/H-Riven/p/9148339.html