洛谷P1196 銀河英雄傳說

大意:你有30000個隊列,第i個隊列中只有iide

有T個操做,1,把某個隊列頭接到另外一個隊列尾。spa

2,問兩個元素之間的距離。code

本題主要有三種解法。blog

①帶權並查集。隊列

具體來講就是,並查集維護當前集合的大小,這個點距離表明元(隊首)的邊數。io

而後把合併和路徑壓縮魔改一下。詢問的時候就直接取距離之差。event

 1 #include <cstdio>
 2 
 3 const int N = 30010;
 4 
 5 int fa[N], sum[N], siz[N];
 6 char str[5];
 7 
 8 inline int find(int x, int &s) {
 9     if(fa[x] == x) {
10         s = 0;
11         return x;
12     }
13     int t = find(fa[x], s);
14     s += sum[x];
15     sum[x] = s;
16     return fa[x] = t;
17 }
18 
19 inline void merge(int x, int y) {
20     int a, b;
21     x = find(x, a);
22     y = find(y, b);
23     fa[x] = y;
24     sum[x] = siz[y];
25     siz[y] += siz[x];
26     return;
27 }
28 
29 inline int ask(int x, int y) {
30     int a, b;
31     x = find(x, a);
32     y = find(y, b);
33     if(x != y) {
34         return -1;
35     }
36     return (a > b ? a - b : b - a) - 1;
37 }
38 
39 int main() {
40     int n;
41     scanf("%d", &n);
42     for(int i = 1; i <= 30000; i++) {
43         fa[i] = i;
44         siz[i] = 1;
45     }
46     for(int i = 1, x, y; i <= n; i++) {
47         scanf("%s%d%d", str, &x, &y);
48         if(str[0] == 'M') {
49             merge(x, y);
50         }
51         else {
52             printf("%d\n", ask(x, y));
53         }
54     }
55 
56     return 0;
57 }
AC代碼

②平衡樹class

這個太暴力了......開30000顆平衡樹便可。cli

③離線(kruskal重構樹)重構

重構的時候把順序搞一下,而後提出來DFS序,直接回答詢問。

相關文章
相關標籤/搜索