【HDOJ】3686 Traffic Real Time Query System

这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图。转化为lca求解。
结合点——双连通分量与LCA。

  1 /* 3686 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 
 43 typedef struct {
 44     int u, v, f, nxt;
 45 } edge_t;
 46 
 47 typedef struct {
 48     int v, nxt;
 49 } edge;
 50 
 51 const int maxv = 10005;
 52 const int maxe = 200005;
 53 int head[maxv], l, top;
 54 int pre[maxv], low[maxv];
 55 bool iscut[maxv];
 56 int cnt[maxv], dfs_clock, bcc_cnt;
 57 int bn[maxe];
 58 int S[maxe];
 59 vi bcc[maxv];
 60 edge_t E[maxe];
 61 int n, m;
 62 
 63 const int maxvv = maxv * 2;
 64 int mark[maxvv];
 65 int head_[maxvv], l_;
 66 int cutn[maxvv];
 67 edge E_[maxe];
 68 
 69 int deep[maxvv], beg[maxvv];
 70 int V[maxvv<<1], D[maxvv<<1];
 71 
 72 int dp[16][maxvv<<1];
 73 
 74 void init_() {
 75     memset(head_, -1, sizeof(head_));
 76     memset(mark, 0, sizeof(mark));
 77     l_ = 0;
 78 }
 79 
 80 void addEdge_(int u, int v) {
 81     E_[l_].v = v;
 82     E_[l_].nxt = head_[u];
 83     head_[u] = l_++;
 84     
 85     E_[l_].v = u;
 86     E_[l_].nxt = head_[v];
 87     head_[v] = l_++;
 88 }
 89 
 90 void init() {
 91     l = dfs_clock = bcc_cnt = top = 0;
 92     memset(head, -1, sizeof(head));
 93     memset(iscut, false, sizeof(iscut));
 94     memset(cnt, 0, sizeof(cnt));
 95     memset(cutn, 0, sizeof(cutn));
 96     memset(pre, 0, sizeof(pre));
 97     rep(i, 1, n+1)
 98         bcc[i].clr();
 99 }
100 
101 void addEdge(int u, int v) {
102     E[l].u = u;
103     E[l].f = 0;
104     E[l].v = v;
105     E[l].nxt = head[u];
106     head[u] = l++;
107 
108     E[l].u = v;
109     E[l].f = 0;
110     E[l].v = u;
111     E[l].nxt = head[v];
112     head[v] = l++;
113 }
114 
115 void tarjan(int u, int fa) {
116     int v, k;
117 
118     low[u] = pre[u] = ++dfs_clock;
119     for (k=head[u]; k!=-1; k=E[k].nxt) {
120         if (E[k].f)
121             continue;
122         E[k].f = E[k^1].f = 1;
123         v = E[k].v;
124         S[top++] = k;
125         if (!pre[v]) {
126             tarjan(v, u);
127             low[u] = min(low[u], low[v]);
128             if (low[v] >= pre[u]) {
129                 iscut[u] = true;
130                 ++cnt[u];
131                 bcc_cnt++;
132                 while (1) {
133                     int kk = S[--top];
134                     bn[kk>>1] = bcc_cnt;
135                     bcc[E[kk].u].pb(bcc_cnt);
136                     bcc[E[kk].v].pb(bcc_cnt);
137                     if (kk == k)
138                         break;
139                 }
140             }
141         } else {
142             low[u] = min(low[u], pre[v]);
143         }
144     }
145 }
146 
147 void dfs(int u, int fa, int d) {
148     mark[u] = dfs_clock;
149     deep[u] = d;
150     V[++top] = u;
151     D[top] = d;
152     beg[u] = top;
153 
154     int v, k;
155 
156     for (k=head_[u]; k!=-1; k=E_[k].nxt) {
157         v = E_[k].v;
158         if (v == fa)
159             continue;
160         dfs(v, u, d+1);
161         V[++top] = u;
162         D[top] = d;
163     }
164 }
165 
166 void init_RMQ(int n) {
167     int i, j;
168 
169     for (i=1; i<=n; ++i)
170         dp[0][i] = i;
171     for (j=1; (1<<j)<=n; ++j)
172         for (i=1; i+(1<<j)-1<=n; ++i)
173             if (D[dp[j-1][i]] < D[dp[j-1][i+(1<<(j-1))]])
174                 dp[j][i] = dp[j-1][i];
175             else
176                 dp[j][i] = dp[j-1][i+(1<<(j-1))];
177 }
178 
179 int RMQ(int l, int r) {
180     if (l > r)
181         swap(l, r);
182 
183     int k = 0;
184 
185     while (1<<(k+1) <= r-l+1)
186         ++k;
187 
188     if (D[dp[k][l]] < D[dp[k][r-(1<<k)+1]])
189         return V[dp[k][l]];
190     else
191         return V[dp[k][r-(1<<k)+1]];
192 }
193 
194 void solve() {
195     int u, v, lca;
196     
197     rep(i, 1, n+1) {
198         if (!pre[i]) {
199             tarjan(i, -1);
200             if (cnt[i] <= 1)
201                 iscut[i] = false;
202         }
203     }
204 
205     int cid = bcc_cnt;
206     
207     init_();
208     cid = bcc_cnt;
209     for (u=1; u<=n; ++u) {
210         if (!iscut[u])
211             continue;
212         sort(all(bcc[u]));
213         cutn[++cid] = 1;
214         addEdge_(cid, bcc[u][0]);
215         int sz = SZ(bcc[u]);
216         rep(i, 1, sz) {
217             if (bcc[u][i] != bcc[u][i-1]) {
218                 addEdge_(cid, bcc[u][i]);
219             }
220         }
221     }
222 
223     top = 0;
224     ++dfs_clock;
225     rep(i, 1, cid+1) {
226         if (mark[i] != dfs_clock)
227             dfs(i, 0, 0);
228     }
229 
230     init_RMQ(top);
231 
232     int q;
233     int ans;
234 
235     scanf("%d", &q);
236     while (q--) {
237         scanf("%d %d", &u, &v);
238         u = bn[u-1];
239         v = bn[v-1];
240         lca = RMQ(beg[u], beg[v]);
241         ans = (deep[u]+deep[v] - deep[lca]*2 + 1) / 2;
242         printf("%d
", ans);
243     }
244 }
245 
246 int main() {
247     ios::sync_with_stdio(false);
248     #ifndef ONLINE_JUDGE
249         freopen("data.in", "r", stdin);
250         freopen("data.out", "w", stdout);
251     #endif
252 
253     int u, v;
254 
255     while (scanf("%d %d", &n, &m)!=EOF && (n||m)) {
256         init();
257         rep(i, 0, m) {
258             scanf("%d %d", &u, &v);
259             addEdge(u, v);
260         }
261 
262         solve();
263     }
264 
265     #ifndef ONLINE_JUDGE
266         printf("time = %d.
", (int)clock());
267     #endif
268 
269     return 0;
270 }
原文地址:https://www.cnblogs.com/bombe1013/p/5183686.html