这是一道写起来比较顺手的题目
没有各种奇怪的细节,基本就是Kruskal和倍增LCA的模板。。
题目大意:对于一个无向带权图,询问两点之间一条路,使得这条路上的最长边最小,输出最小最长边的的值
那么既然要使最长边最短,我们可以先构造一棵最小生成树
由于kruskal已经将边排了序了,所以对于这棵树,每条边都尽量最短了
然后我们再进行lca求出两点路径上的最长边,即为答案
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 15010; 6 struct node{ 7 int u,v,cost,next; 8 }e[maxn*4],et[maxn*2]; 9 int head[maxn],n,m,K,tot,logn,u,v; 10 int f[maxn],dep[maxn],fa[maxn][22],mx[maxn][22]; 11 12 void insert(int u, int v, int c){ 13 e[++tot].u=u; e[tot].v=v; e[tot].cost=c; e[tot].next=head[u]; head[u]=tot; 14 } 15 16 bool cmp(node a, node b){ 17 return a.cost<b.cost; 18 } 19 20 int find(int x){ 21 return f[x]==x?x:f[x]=find(f[x]); 22 } 23 24 void MST(){ 25 for (int i=1; i<=n; i++) f[i]=i; 26 for (int i=1; i<=m; i++){ 27 int fx=find(et[i].u), fy=find(et[i].v); 28 if (fx!=fy){ 29 f[fy]=fx; 30 insert(et[i].u,et[i].v,et[i].cost); 31 insert(et[i].v,et[i].u,et[i].cost); 32 } 33 } 34 } 35 36 void dfs(int u, int f, int d, int cost){ 37 dep[u]=d; fa[u][0]=f; mx[u][0]=cost; 38 for (int i=1; i<=logn; i++) fa[u][i]=fa[fa[u][i-1]][i-1]; 39 for (int i=1; i<=logn; i++) mx[u][i]=max(mx[u][i-1],mx[fa[u][i-1]][i-1]); 40 for (int i=head[u]; i!=-1; i=e[i].next) 41 if (e[i].v!=f) dfs(e[i].v,u,d+1,e[i].cost); 42 } 43 44 int lca_max(int u, int v){ 45 int ans=0; 46 if (dep[u]>dep[v]) swap(u,v); 47 while (dep[u]<dep[v]){ 48 for (int i=logn; i>=0; i--) 49 if (dep[u]<dep[fa[v][i]]){ 50 ans=max(ans,mx[v][i]); 51 v=fa[v][i]; 52 } 53 ans=max(ans,mx[v][0]); 54 v=fa[v][0]; 55 } 56 if (u==v) return ans; 57 for (int i=logn; i>=0; i--){ 58 if (fa[u][i]!=fa[v][i]){ 59 ans=max(ans,max(mx[v][i],mx[u][i])); 60 u=fa[u][i]; v=fa[v][i]; 61 } 62 } 63 ans=max(ans,max(mx[u][0],mx[v][0])); 64 return ans; 65 } 66 67 int main(){ 68 scanf("%d%d%d", &n, &m, &K); 69 tot=-1; memset(head,-1,sizeof(head)); 70 while ((1<<logn)<n) logn++; 71 for (int i=1; i<=m; i++) 72 scanf("%d%d%d", &et[i].u, &et[i].v, &et[i].cost); 73 sort(et+1,et+1+m,cmp); 74 MST(); 75 dfs(1,0,1,0); 76 while (K--){ 77 scanf("%d%d", &u, &v); 78 printf("%d ", lca_max(u,v)); 79 } 80 return 0; 81 }