洛谷P1967货车运输
Posted Koreyoshi.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1967货车运输相关的知识,希望对你有一定的参考价值。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
#define INF 0xfffff
using namespace std;
int n, m, q, x, y, cnt;
int head[N], nxt[N*2], to[N*2], w[N*2], p[N*5], f[N][20], minv[N][20], dep[N];
struct Edge{
int x, y, z;
bool operator < (const Edge& rhs) const {
return z > rhs.z;
}
}e[N*5];
inline void read(int& x)
{
x = 0; char ch = getchar();
while(ch < ‘0‘ || ch > ‘9‘) ch = getchar();
while(ch >= ‘0‘ && ch <= ‘9‘) x = x*10 + ch - ‘0‘, ch = getchar();
}
inline void Add(int x, int y, int z)
{
to[cnt] = y;
w[cnt] = z;
nxt[cnt] = head[x];
head[x] = cnt++;
}
inline int find(int x)
{
return p[x] == x ? x : p[x] = find(p[x]);
}
inline void kruskal()
{
for(int i=0;i<m;i++) p[i] = i;
sort(e, e+m);
for(int i=0;i<m;i++)
if(find(e[i].x) != find(e[i].y)){
Add(e[i].x, e[i].y, e[i].z);
Add(e[i].y, e[i].x, e[i].z);
p[find(e[i].x)] = find(e[i].y);
}
}
inline void DFS(int x, int p)
{
for(int i=head[x];~i;i=nxt[i])
if(i != p){
dep[to[i]] = dep[x] + 1;
f[to[i]][0] = x;
minv[to[i]][0] = w[i];
DFS(to[i], i^1);
}
}
inline int lca(int x, int y)
{
int ans = INF;
if(dep[x] > dep[y]) swap(x, y);
for(int i=15;i>=0;i--) if(dep[f[y][i]] >= dep[x]){
ans = min(ans, minv[y][i]);
y = f[y][i];
}
if(x == y) return ans;
for(int i=15;i>=0;i--) if(f[x][i] != f[y][i]) {
ans = min(ans, min(minv[x][i], minv[y][i]));
x = f[x][i];
y = f[y][i];
}
return f[x][0] == 0 ? -1 : min(ans, min(minv[x][0], minv[y][0]));
}
int main()
{
read(n); read(m);
for(int i=0;i<m;i++)
read(e[i].x), read(e[i].y), read(e[i].z);
memset(head, -1, sizeof(head));
kruskal();
dep[1] = 1;
DFS(1, -1);
for(int j=1;j<=15;j++)
for(int i=1;i<=n;i++){
f[i][j] = f[f[i][j-1]][j-1];
minv[i][j] = min(minv[i][j-1], minv[f[i][j-1]][j-1]);
}
read(q);
while(q--){
read(x); read(y);
printf("%d\n", lca(x, y));
}
return 0;
}
以上是关于洛谷P1967货车运输的主要内容,如果未能解决你的问题,请参考以下文章
洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增