【HDOJ】4612 Warm up

双连通缩点+求树的直径,图论基础题目。

  1 /* 4612 */
  2 #pragma comment(linker, "/STACK:1024000000,1024000000")
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <cstdlib>
 10 using namespace std;
 11 
 12 #define MAXV 200005
 13 #define MAXE 1000005
 14 
 15 typedef struct {
 16     int v, next;
 17 } Edge_t;
 18 
 19 Edge_t E[MAXE*2];
 20 vector<int> vc[MAXV];
 21 int low[MAXV], pre[MAXV];
 22 int bn[MAXV];
 23 int S[MAXV], top;
 24 int head[MAXV], L;
 25 bool visit[MAXV];
 26 int dfs_clock, block;
 27 int n, m;
 28 
 29 void addEdge(int u, int v) {
 30     E[L].v = v;
 31     E[L].next = head[u];
 32     head[u] = L++;
 33 }
 34 
 35 void init() {
 36     memset(head, -1, sizeof(int)*(n+1));
 37     memset(pre, 0, sizeof(int)*(n+1));
 38     memset(bn, 0, sizeof(int)*(n+1));
 39     dfs_clock = block = L = top = 0;
 40 }
 41 
 42 void tarjan(int u, int fa) {
 43     int i, j, k, v;
 44     
 45     S[top++] = u;
 46     pre[u] = low[u] = ++dfs_clock;
 47     for (i=head[u]; i!=-1; i=E[i].next) {
 48         if (i == (fa^1))
 49             continue;
 50         v = E[i].v;
 51         if (!pre[v]) {
 52             tarjan(v, i);
 53             low[u] = min(low[u], low[v]);
 54         } else if (!bn[v]) {
 55             low[u] = min(low[u], pre[v]);
 56         }
 57     }
 58     if (low[u] == pre[u]) {
 59         ++block;
 60         do {
 61             bn[S[--top]] = block;
 62         } while (S[top]!=u);
 63     }
 64 }
 65 
 66 void solve() {
 67     queue<int> Q;
 68     int i, j, k;
 69     int u = 1, v;
 70     
 71     memset(pre, 0, sizeof(int)*(block+1));
 72     pre[u] = 1;
 73     Q.push(u);
 74     while (!Q.empty()) {
 75         u = Q.front();
 76         Q.pop();
 77         for (i=0; i<vc[u].size(); ++i) {
 78             v = vc[u][i];
 79             if (!pre[v]) {
 80                 pre[v] = 1;
 81                 Q.push(v);
 82             }
 83         }
 84     }
 85     
 86     memset(pre, 0, sizeof(int)*(block+1));
 87     pre[u] = 1;
 88     Q.push(u);
 89     while (!Q.empty()) {
 90         u = Q.front();
 91         Q.pop();
 92         k = pre[u];
 93         for (i=0; i<vc[u].size(); ++i) {
 94             v = vc[u][i];
 95             if (!pre[v]) {
 96                 pre[v] = k+1;
 97                 Q.push(v);
 98             }
 99         }
100     }
101     
102     printf("%d\n", block-pre[u]);
103 }
104 
105 int main() {
106     int i, j, k;
107     
108     #ifndef ONLINE_JUDGE
109         freopen("data.in", "r", stdin);
110         freopen("data.out", "w", stdout);
111     #endif
112     
113     while (scanf("%d %d",&n,&m)!=EOF && (n||m)) {
114         init();
115         for (i=0; i<m; ++i) {
116             scanf("%d %d", &j, &k);
117             addEdge(j, k);
118             addEdge(k, j);
119         }
120         for (i=1; i<=n; ++i)
121             if (!pre[i])
122                 tarjan(i, -1);
123         for (i=1; i<=block; ++i)
124             vc[i].clear();
125         for (i=1; i<=n; ++i) {
126             for (j=head[i]; j!=-1; j=E[j].next) {
127                 k = E[j].v;
128                 if (bn[i] != bn[k]) {
129                     // bridge
130                     vc[bn[i]].push_back(bn[k]);
131                     vc[bn[k]].push_back(bn[i]);
132                 }
133             }
134         }
135         solve();
136     }
137     
138     return 0;
139 }

 

posted on 2015-03-20 22:12  Bombe  阅读(148)  评论(0编辑  收藏  举报

导航