UVA11354[Bond] 倍增求LCA+Kruskal求最小瓶颈生成树
来源:互联网 发布:美图秀秀mac官方下载 编辑:程序博客网 时间:2024/05/22 01:44
题目链接
题意:给定一个无向带权图,有一些询问,问u,v点之间的路径上最大边权值的最小为多少?也就是问u,v之间的最小瓶颈路的最大边长为?
solution:先求出最小瓶颈生成树,再倍增求出u,v的LCA,顺便算出ans值。
最小瓶颈生成树详解
#include <cstdio>#include <iostream>#include <vector>#include <cstring>#include <algorithm>using namespace std;const int N = 5e4 + 7;const int M = 1e5 + 10;struct E{ int u, v, w;}e[M];struct Edge{ int u, v, w; Edge(int u,int v,int w):u(u),v(v),w(w){};}; vector<Edge> edges;vector<int> G[N];void addeage(int u, int v, int w){ edges.push_back(Edge(u,v,w)); int kk=edges.size(); G[u].push_back(kk-1);}int n, m;int pa[N];int find(int x){ int r=x; while( r!=pa[r] ) r=pa[r]; int i=x, j; while( i!=pa[i] ) { j=pa[i]; pa[i]=r; i=j; } return r;}bool merge(int x, int y){ x=find(x), y=find(y); if( x==y ) return false; pa[x]=y; return true;}bool cmp(E a, E b){ return a.w<b.w;}void Kruskal(){ sort(e,e+m,cmp); int num=0; for ( int i=1; i<=n; i++ ) pa[i]=i, G[i].clear(); edges.clear(); for ( int i=0; i<m; i++ ) if( merge(e[i].u,e[i].v) && num<n-1 ){ addeage(e[i].u,e[i].v,e[i].w); addeage(e[i].v,e[i].u,e[i].w); num++; } }int cost[N], dep[N], fa[N];void dfs(int u,int fat){ for (int i=0; i<G[u].size(); i++ ){ Edge e=edges[G[u][i]]; int vv=e.v, ww=e.w; if( vv==fat ) continue; dep[vv]=dep[u]+1; cost[vv]=ww; fa[vv]=u; dfs(vv,u); }}int anc[N][20], mx[N][20];//————————倍增求LCA——————// void prepocess(){ memset(anc,0,sizeof(anc));// anc[i][j]表 示 i 的 第 2^j 级 祖 先 是 谁 memset(mx,0,sizeof(mx)); // mx[i][j] 表 示 i 到 第 2^j 级 祖 先 路 径 上 最 大 值 for ( int i=1; i<=n; i++ ){ anc[i][0]=fa[i]; mx[i][0]=cost[i]; for ( int j=1; (1<<j)<=n; j++ ) anc[i][j]=-1; } for ( int j=1; (1<<j)<=n; j++ ) for ( int i=1; i<=n; i++ ) if( anc[i][j-1]!=-1 ){ int a=anc[i][j-1]; anc[i][j]=anc[a][j-1]; mx[i][j]=max( mx[i][j-1], mx[a][j-1]); // 有 点 像 ST 表 }}int query(int p, int q){ if( dep[p]<dep[q] ) swap(p,q); int lg, ans=0; for ( lg=1; (1<<lg)<=dep[p]; lg++ ); lg--; for ( int i=lg; i>=0; i-- ) if( dep[p]-dep[q]>=(1<<i) ){ ans=max(ans, mx[p][i]); p=anc[p][i]; // p 往 上 跳 } if( p==q ) return ans; for ( int j=19; j>=0; j-- ) if( anc[p][j]!=-1 && anc[p][j]!=anc[q][j] ){ ans=max(ans, mx[p][j]); p=anc[p][j]; ans=max(ans, mx[q][j]); q=anc[q][j]; // p,q 一 起 跳 } ans=max(ans, cost[p]); ans=max(ans, cost[q]); return ans;}//——————————————————————————// int main(){ int ka=0; while( scanf("%d%d", &n, &m )==2 ){ if(ka>0) printf("\n"); ka++; for ( int i=0; i<m; i++ )scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w); Kruskal(); dep[1]=0; fa[1]=0; dfs(1,0); prepocess(); int Q; scanf("%d", &Q); while( Q-- ){ int x, y; scanf("%d%d", &x, &y ); printf("%d\n", query(x,y) ); } } }
阅读全文
0 0
- UVA11354[Bond] 倍增求LCA+Kruskal求最小瓶颈生成树
- uva11354 - Bond 最小瓶颈路+LCA
- UVA 11354 Bond(最小生成树+lca+倍增求祖先节点)
- 最小生成树+LCA+uva11354
- 最小生成树和倍增法求lca(Uva11354Bond)
- 【UVa】11354 Bond 最小生成树,动态LCA,倍增思想
- UVA 11354 Bond(最小生成树+LCA倍增)
- UVa 11354 Bond 最小生成树+LCA倍增
- UVA 11354 Bond 瓶颈路 最小生成树+LCA类似
- 洛谷1967 火车运输 kruskal求最大生成树 倍增LCA维护最小值
- CodeVS1519 过路费【Kruskal+倍增求LCA】
- KrusKal求最小生成树
- UVA11354 - Bond瓶颈路
- HDU-1233(kruskal求最小生成树)
- hdu1863(kruskal求最小生成树)
- hdu1879(kruskal求最小生成树)
- Kruskal算法求最小生成树
- ZOJ1203 kruskal求最小生成树
- win10 tensorflow-gpu 环境搭建
- CSS中zoom和transform:scale的区别
- jquery 表格的增加删除和修改及设置奇偶行颜色
- javascript 得到文件后缀名
- PHP 缩放图片
- UVA11354[Bond] 倍增求LCA+Kruskal求最小瓶颈生成树
- PHP访问MySql数据库 初级篇
- PHP访问MySql数据库 中级篇 Smarty技术
- PHP访问MySql数据库 高级篇 AJAX技术
- JSON进阶第一篇 在PHP与javascript 中使用JSON
- JSON进阶第二篇 AJAX方式传递JSON数据
- Java程序发送邮件
- JSON进阶第三篇 apache多域名及JSON的跨域问题(JSONP)
- PHP读写XML文件