超级好题,完美考核了2个算法:(最小生成树+lca);
当然,也可以用“树链剖分”来替代“lca”。如果想学树链剖分,请拉到最后!
题目大意:
n个点的无向图内,m次询问:x 点到 y 点的路径中,最大值是多少?如果 x与y不连通,输出-1;
解法分析:
1、在无向图中,求两点的连通性,还要求两点之间道路的最值,应该先建树(最小生成树);
2、多次询问 x与 y之间的道路最值,就是树上的两点的关系,用“最近公共祖先(lca)”来实现;
3、用倍增数组来优化求 lca的过程。
算法介绍:
1、最小生成树:就是用最少的边(n-1条),把全图连通;
这里用k算法,方法是:对原图的边进行排序,再取其中的最多(n-1)条边来连接 n个点(就是一棵树(无环)了);
2、lca:求树上的两个点的最近公共祖先;
这里用倍增数组进行优化跳跃,倍增在这里表现在一个二维数组(如果之前没接触过的孩子,但看本题解比较难懂,加油哦)
上代码:(部分细节,还是在代码注解中)
#include<cstdio>
#include<algorithm>
using namespace std;
const int mx=100005,inf=999999999;//n的最值
int n,m,len=0;;
struct nod{int x,y,c,gg;}e[mx*5],b[mx*2];
int h[mx],d[mx],f[mx],fa[mx],p[mx][30],w[mx][30];
bool cmp(nod x,nod y) { return x.c>y.c; }//排序的参数
int ch(int x) { if(f[x]==x) return x; return f[x]=ch(f[x]); }//并查集的板子
void ins(int x,int y,int c