Hdu 4612 Warm up (双连通分支+树的直径)

题目链接:

  Hdu 4612 Warm up

题目描述:

  给一个无向连通图,问加上一条边后,桥的数目最少会有几个?

解题思路:

  题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然后缩点重新建图,用bfs求树的直径,直径的长度就是减去桥的数目。

这个题目需要手动扩展,而且手动扩展的话要用C++提交,G++re哭了。

  1 #include <cstdio>
  2 #include <queue>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #pragma comment(linker, "/STACK:1024000000,1024000000")
  7 using namespace std;
  8 
  9 const int maxn = 200005;
 10 struct node
 11 {
 12     int to, next;
 13 }edge[10*maxn], Edge[2*maxn];
 14 int vis[maxn], dist[maxn];
 15 int head[maxn], low[maxn], dfn[maxn], id[maxn], Head[maxn];
 16 int stack[maxn], tot, Tot, ntime, top, cnt, Max, end_p;
 17 
 18 void init ()
 19 {
 20     tot = ntime = top = Tot = cnt = Max = end_p = 0;
 21     memset (id, 0, sizeof(id));
 22     memset (low, 0, sizeof(low));
 23     memset (dfn, 0, sizeof(dfn));
 24     memset (head, -1, sizeof(head));
 25     memset (stack, 0, sizeof(stack));
 26     memset (Head, -1, sizeof(Head));
 27 }
 28 void Add (int from, int to)
 29 {
 30     Edge[Tot].to = to;
 31     Edge[Tot].next = Head[from];
 32     Head[from] = Tot ++;
 33 }
 34 void add (int from, int to)
 35 {
 36     edge[tot].to = to;
 37     edge[tot].next = head[from];
 38     head[from] = tot ++;
 39 }
 40 void Tarjan (int u, int father)
 41 {
 42     int k = 0;
 43     low[u] = dfn[u] = ++ntime;
 44     stack[top++] = u;
 45     for (int i=head[u]; i!=-1; i=edge[i].next)
 46     {
 47         int v = edge[i].to;
 48         if (v == father && !k)
 49         {
 50             k ++;
 51             continue;
 52         }
 53         if (!dfn[v])
 54         {
 55             Tarjan (v, u);
 56             low[u] = min (low[u], low[v]);
 57         }
 58         else
 59             low[u] = min (low[u], dfn[v]);
 60     }
 61     if (low[u] == dfn[u])
 62     {
 63         cnt ++;
 64         while (1)
 65         {
 66             int v = stack[--top];
 67             id[v] = cnt;
 68             if (v == u)
 69                 break;
 70         }
 71     }
 72 }
 73 void bfs (int s)
 74 {
 75     queue<int>Q;
 76     int u, v;
 77     memset (vis, 0,sizeof(vis));
 78     vis[s] = 1;
 79     dist[s] = 0;
 80     Q.push(s);
 81     while (!Q.empty())
 82     {
 83         u = Q.front();
 84         Q.pop();
 85         for (int i=Head[u]; i!=-1; i=Edge[i].next)
 86         {
 87             v = Edge[i].to;
 88             if (!vis[v])
 89             {
 90                 vis[v] = 1;
 91                 dist[v] = dist[u] + 1;
 92                 Q.push(v);
 93                 if (dist[v] > Max)
 94                 {
 95                     Max = dist[v];
 96                     end_p = v;
 97                 }
 98             }
 99         }
100     }
101 }
102 void solve (int n)
103 {
104     int sum = 0;
105     Tarjan (1, 0);
106     for (int i=1; i<=n; i++)
107         for (int j=head[i]; j!=-1; j=edge[j].next)
108         {
109             int u = id[i];
110             int v = id[edge[j].to];
111             if (v != u)
112                 {
113                     Add (u, v);
114                     sum ++;
115                 }
116         }
117     sum /= 2;
118     bfs (1);
119     bfs (end_p);
120     printf ("%d\n", sum - Max);
121 }
122 int main ()
123 {
124     int n, m;
125     while (scanf ("%d %d", &n, &m), n+m)
126     {
127         init ();
128         while (m --)
129         {
130             int u, v;
131             scanf ("%d %d", &u, &v);
132             add (u, v);
133             add (v, u);
134         }
135         solve (n);
136     }
137     return 0;
138 }

 

posted @ 2015-07-24 19:09  罗茜  阅读(289)  评论(0编辑  收藏  举报