题目意思大概是要求路径的最小权值的最大值,我们可以将权值小的无关紧要的边去掉;
方法可以使用最大生成树重新建图,然后再最大生成树上用LCA来回答每一个询问.
这里博主使用倍增求LCA的,当时太菜了,没想到用倍增直接来存权值,就通过每个点的fa数组来求到LCA路径上的最小权值;
1 #include <bits/stdc++.h>
2 #define N 100000+5
3 #define M 500000+5
4 using namespace std;
5 struct node
6 {
7 int u,v,wei;
8 }a[M];
9 int n,m,lgn,q;
10 int ans;
11 int f[N][25],fa[N],vis[N],depth[N],fw[N];
12 vector <int> edge[N],w[N],wn[N];
13 bool cmp(node a,node b)
14 {
15 return a.wei>b.wei;
16 }
17 int Find(int u)
18 {
19 while(u!=fa[u])
20 {
21 fa[u]=fa[fa[u]];
22 u=fa[u];
23 }
24 return u;
25 }
26 void Kruskal()//求最大生成树
27 {
28 for(int i=1;i<=m;i++)
29 {
30 int u=a[i].u,v=a[i].v,wei=a[i].wei;
31 int fau=Find(u),fav=Find(v);
32 if(fau!=fav)
33 {
34 fa[fau]=fav;
35 edge[u].push_back(v);
36 w[u].push_back(wei);
37 edge[v].push_back(u);
38 w[v].push_back(wei);
39 }
40 }
41 }
42 void dfs(int u)
43 {
44 vis[u]=1;
45 for(int i=0;i<edge[u].size();i++)
46 {
47 int now=edge[u][i];
48 if(!vis[now])
49 {
50 f[now][0]=u;
51 depth[now]=depth[u]+1;
52 fw[now]=w[u][i];
53 dfs(now);
54 }
55 }
56 }
57 void getfather()//倍增
58 {
59 for(int j=1;j<=lgn;j++)
60 {
61 for(int i=1;i<=n;i++)
62 {
63 f[i][j]=f[f[i][j-1]][j-1];
64 }
65 }
66 }
67 int LCA(int u,int v)//LCA模板
68 {
69 if(depth[u]<depth[v]) swap(u,v);
70 int dist=depth[u]-depth[v];
71 int j=0;
72 while(dist)
73 {
74 if(dist&1) u=f[u][j];
75 dist>>=1;
76 j++;
77 }
78 if(u==v) return u;
79 for(int j=lgn-1;j>=0;j--)
80 {
81 if(f[u][j]!=f[v][j])
82 {
83 u=f[u][j];
84 v=f[v][j];
85 }
86 }
87 return f[u][0];
88 }
89 void work(int u,int com)//求到LCA路径上的最小权值
90 {
91 while(u!=com)
92 {
93 int nxt=f[u][0];
94 ans=min(ans,fw[u]);
95 u=nxt;
96 }
97 }
98 int main()
99 {
100 scanf("%d%d",&n,&m);
101 lgn=log2(n);
102 for(int i=1;i<=m;i++)
103 {
104 scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].wei);
105 }
106 for(int i=1;i<=n;i++) fa[i]=i;
107 sort(a+1,a+m+1,cmp);
108 Kruskal();
109 for(int i=1;i<=n;i++)
110 {
111 if(!vis[i]) dfs(i);
112 }
113 getfather();
114 scanf("%d",&q);
115 for(int i=1;i<=q;i++)
116 {
117 ans=INT_MAX;
118 int u,v;
119 scanf("%d%d",&u,&v);
120 int lca=LCA(u,v);
121 work(u,lca);
122 work(v,lca);
123 if(lca==0)printf("-1\n");
124 else printf("%d\n",ans);
125 }
126 return 0;
127 }
知识兔