【树上LCA】P1967 货车运输

夙愿已清 提交于 2019-12-01 11:48:46
  1 #include<iostream>
  2 #include<string>
  3 #include<queue>
  4 #include<stack>
  5 #include<vector>
  6 #include<map>
  7 #include<cstdio>
  8 #include<cstdlib>
  9 #include<algorithm>
 10 #include<set>
 11 #include<iomanip>
 12 #include<cstring>
 13 #include<cmath>
 14 #include<limits>
 15 using namespace std;
 16 
 17 #define au auto
 18 #define debug(i) cout<<"<debug>"<<i<<"<\debug>"<<endl
 19 #define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
 20 #define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
 21 #define LLL __int128
 22 #define Re register
 23 #define il inline
 24 #define mem(a,b) memset(a,(b),sizeof(a))
 25 typedef pair<int, int> intpair;
 26 typedef long long int LL;
 27 const int INF = 0x3f3f3f3f;
 28 const long long int INFLL = 0x3f3f3f3f3f3f3f3f;
 29 
 30 const int maxn = 100010;
 31 int fa[maxn];
 32 
 33 int find(int x)
 34 {
 35     if (fa[x] == x) return x;
 36     fa[x] = find(fa[x]);
 37     return fa[x];
 38 }
 39 
 40 void merge(int a, int b)
 41 {
 42     fa[find(a)] = find(b);
 43 }
 44 
 45 bool check(int a, int b)
 46 {
 47     return find(a) == find(b);
 48 }
 49 
 50 int n, m;
 51 int cnt;
 52 
 53 struct Edge
 54 {
 55     int u, nxt, w;
 56 }tr[300010];
 57 
 58 struct Edge1
 59 {
 60     int u, v, w;
 61     bool operator>(Edge1 s)const
 62     {
 63         return w > s.w;
 64     }
 65 }e[300010];
 66 
 67 int head[maxn];
 68 
 69 void add(int a, int b, int w)
 70 {
 71     tr[++cnt].u = b;
 72     tr[cnt].nxt = head[a];
 73     head[a] = cnt;
 74     tr[cnt].w = w;
 75 }
 76 
 77 void kruskal()
 78 {
 79     sort(e + 1, e + m + 1, greater<Edge1>());
 80     mfor(i, 1, n) fa[i] = i;
 81     int tot = 1;
 82     mfor(i, 1, m)
 83     {
 84         if (!check(e[i].u, e[i].v))
 85         {
 86             merge(e[i].u, e[i].v);
 87             add(e[i].u, e[i].v, e[i].w);
 88             add(e[i].v, e[i].u, e[i].w);
 89             if (++tot >= n)
 90             {
 91                 break;
 92             }
 93         }
 94     }
 95 }
 96 
 97 int d[maxn];
 98 int dis[maxn];
 99 int f[maxn][100];
100 int w[maxn][100];
101 int k;
102 int ans;
103 
104 void dfs(int x)
105 {
106     for (int i = head[x]; i; i = tr[i].nxt)
107     {
108         int u = tr[i].u;
109         if (d[u]) continue;
110         d[u] = d[x] + 1;
111         f[u][0] = x;
112         w[u][0] = tr[i].w;
113         dfs(u);
114     }
115 }
116 
117 int lca(int a, int b)
118 {
119     if (!check(a, b)) return -1;
120     ans = INF;
121     if (d[a] < d[b]) swap(a, b);
122     mrep(i, k, 0)
123     {
124         if (d[f[a][i]] >= d[b])
125         {
126             ans = min(ans, w[a][i]);
127             a = f[a][i];
128         }
129     }
130     if (a == b) return a;
131     mrep(i, k, 0)
132     {
133         if (f[a][i] != f[b][i])
134         {
135             ans = min(ans, min(w[a][i], w[b][i]));
136             a = f[a][i];
137             b = f[b][i];
138         }
139     }
140     ans = min(ans, min(w[a][0], w[b][0]));
141     return f[a][0];
142 }
143 
144 int main()
145 {
146     cin >> n >> m;
147     k = (int)(log(n) / log(2)) + 1;
148     mfor(i, 1, m)
149     {
150         cin >> e[i].u >> e[i].v >> e[i].w;
151     }
152     kruskal();
153     mfor(i, 1, n)
154     {
155         if (!d[i])
156         {
157             d[i] = 1;
158             dfs(i);
159             f[i][0] = i;
160             w[i][0] = INF;
161         }
162     }
163     mfor(i, 1, k)
164     {
165         mfor(j, 1, n)
166         {
167             f[j][i] = f[f[j][i - 1]][i - 1];
168             w[j][i] = min(w[j][i - 1], w[f[j][i - 1]][i - 1]);
169         }
170     }
171     int T;
172     cin >> T;
173     mfor(i, 1, T)
174     {
175         int a, b;
176         cin >> a >> b;
177         int t = lca(a, b);
178         if (t == -1) cout << t << endl;
179         else cout << ans << endl;
180     }
181 }
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!