[2019 CSP-S赛前集训] [洛谷P1967] 货车运输
题目链接:https://www.luogu.org/problem/P1967
题目意思大概是要求路径的最小权值的最大值,我们可以将权值小的无关紧要的边去掉;
方法可以使用最大生成树重新建图,然后再最大生成树上用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 }
转载请注明出处--Xx_queue