洛谷 #1967. 货车运输

版权声明:转载请注明出处 https://blog.csdn.net/qq_41593522/article/details/84501896

题意

在图上从x到y找一条简单路径,使得路径上最小值最大

暴力会T

题解

因为需要的是较大的那些边,故可以求最大生成树,然后LCA

调试记录

数组开小了

#include <cstdio>
#include <algorithm>
#include <cstring>
#define INF 0x3f3f3f3f
#define maxn 50005

using namespace std;

int n, m, q, u, v;

struct Node{
	int u, v, l;
}E[maxn];

struct node{
	int to, next, l;
}e[maxn << 1]; int tot = 0, head[maxn];
void addedge(int u, int v, int l){
	e[++tot] = (node){v, head[u], l}; head[u] = tot;
}

int f[maxn];
int getf(int x){
	if (f[x] != x) f[x] = getf(f[x]);
	return f[x];
}
bool cmp(Node a, Node b){ return a.l > b.l; }
void Kruskal(){
	sort(E + 1, E + m + 1, cmp);
	for (int i = 1; i <= n; i++) f[i] = i;
	
	for (int i = 1; i <= m; i++){
		if (getf(E[i].u) != getf(E[i].v)){
			f[getf(E[i].u)] = getf(E[i].v);
			addedge(E[i].u, E[i].v, E[i].l);
			addedge(E[i].v, E[i].u, E[i].l);
		}
	}
}

int fa[maxn][21], l[maxn][21], dep[maxn];
bool vis[maxn];
void dfs(int cur){
	vis[cur] = true;
	for (int i = head[cur]; i; i = e[i].next){
		if (!vis[e[i].to]){
			fa[e[i].to][0] = cur;
			l[e[i].to][0] = e[i].l;
			dep[e[i].to] = dep[cur] + 1;
			dfs(e[i].to);
		}
	}
}

int LCA(int x, int y){
	if (getf(x) != getf(y)) return -1;
	if (dep[x] < dep[y]) swap(x, y);
	
	int ans = INF;
	for (int i = 20; i >= 0; i--){
		if (dep[fa[x][i]] >= dep[y]){
			ans = min(ans, l[x][i]);
			x = fa[x][i];
		}
	}
	
	if (x == y) return ans;
	
	for (int i = 20; i >= 0; i--){
		if (fa[x][i] != fa[y][i]){
			ans = min(ans, min(l[x][i], l[y][i]));
			x = fa[x][i], y = fa[y][i];
		}
	}
	ans = min(ans, min(l[x][0], l[y][0]));
	
	return ans;
}

int main(){
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i++) scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].l);
	
	Kruskal();
	
	memset(vis, false, sizeof vis);
	for (int i = 1; i <= n; i++){
		if (!vis[i]){
			dep[i] = 1;
			l[i][0] = INF;
			fa[i][0] = i;
			dfs(i);
		}
	}
	
	for (int i = 1; i <= 20; i++){
		for (int j = 1; j <= n; j++){
			fa[j][i] = fa[fa[j][i - 1]][i - 1];
			l[j][i] = min(l[j][i - 1], l[fa[j][i - 1]][i - 1]);
		}
	}
	
	scanf("%d", &q);
	while (q--){
		scanf("%d%d", &u, &v);
		printf("%d\n", LCA(u, v));
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41593522/article/details/84501896