Bond UVA
来源:互联网 发布:信用卡代办软件 编辑:程序博客网 时间:2024/06/01 14:36
Bond UVA - 11354
题目大意:
n个点m条边的图,q次询问,找到一条从s到t的一条边,使所有边的最大危险系数最小。
题解:
使最大的危险系数尽量小,答案一定是最小生成树上的边。
为了快速回答询问,用LCA倍增法记录s和t到他们最近公共祖先的最大值。
Code:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define D(x) cout<<#x<<" = "<<x<<" "#define E cout<<endlusing namespace std;const int N = 100005;const int M = 500005;int n,m;int pa[N][21],dep[N],mx[N][21];struct Edge{ int u,v,next,w; Edge(){} Edge(int _u,int _v,int _w){ u=_u; v=_v; w=_w; } bool operator < (const Edge & tp) const { return w < tp.w; }}e[N*2],edge[M];int head[N],ec,edgecnt;void clearEdge(){ memset(head,0,sizeof(head)); ec=0; edgecnt=0; }void add(int a,int b,int w){ //D(a); D(b); D(w); E; ec++; e[ec].u=a; e[ec].v=b; e[ec].w=w; e[ec].next=head[a]; head[a]=ec;}struct UNSet{ int pa[N]; void init(int n){ for(int i=1;i<=n;i++)pa[i]=i; } int find(int x){ if(pa[x]!=x) pa[x]=find(pa[x]); return pa[x]; }} unset;void clearAll(){ clearEdge(); memset(pa,-1,sizeof(pa)); memset(dep,0,sizeof(dep)); memset(mx,-1,sizeof(mx));}void kruskal(){ sort(edge+1,edge+1+edgecnt); unset.init(n); int cnt=0; for(int i=1;i<=edgecnt;i++){ int x=unset.find(edge[i].u); int y=unset.find(edge[i].v); if(x!=y){ unset.pa[x]=y; add(edge[i].u,edge[i].v,edge[i].w); add(edge[i].v,edge[i].u,edge[i].w); if(++cnt==n-1) break; } }}void dfs(int u){ for(int i=head[u];i;i=e[i].next){ int v=e[i].v; if(v==pa[u][0]) continue; pa[v][0]=u; dep[v]=dep[u]+1; mx[v][0]=e[i].w; dfs(v); }}void init(){ for(int j=1;j<20;j++){ for(int i=1;i<=n;i++){ pa[i][j]=pa[pa[i][j-1]][j-1]; mx[i][j]=max(mx[i][j-1],mx[pa[i][j-1]][j-1]); } }}int query(int a,int b){ int ans=-1; if(dep[a]<dep[b]) swap(a,b); int cha=dep[a]-dep[b]; for(int j=0;(1<<j)<=cha;j++){ if(cha&(1<<j)){ //忘了这个,WA了一节课QwQ ans=max(ans,mx[a][j]); a=pa[a][j]; } } if(a!=b){ for(int j=20-1;j>=0;j--){ if(pa[a][j]!=pa[b][j]){ ans=max(ans,max(mx[a][j],mx[b][j])); a=pa[a][j]; b=pa[b][j]; } } ans=max(ans,max(mx[a][0],mx[b][0])); //Take care! } return ans;}int main(){ freopen("a.in","r",stdin); int a,b,w,q; int cas=0; while(~scanf("%d%d",&n,&m) && (n||m)){ if(cas)puts(""); cas++; clearAll(); for(int i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&w); edge[++edgecnt]=Edge(a,b,w); } kruskal(); dfs(1); init(); scanf("%d",&q); for(int i=1;i<=q;i++){ scanf("%d%d",&a,&b); printf("%d\n",query(a,b)); } }}
阅读全文
0 0
- Bond UVA
- UVA 11354 Bond
- UVA 11354 Bond
- uva 11354 - Bond(树链剖分)
- uva 11354 Bond
- UVA 11354 Bond
- uva 11354 bond 倍增
- UVA 11354 Bond
- UVA 11354 Bond
- uva 11354 Bond
- UVA 11354 - Bond(树链剖分)
- UVA 11354 Bond (MST + LCA)
- UVA 11354 Bond(MST + LCA)
- UVA 11354 Bond(prim+LCA,4级)
- uva 11354 bond 最小瓶颈路
- UVA 11354 - Bond (最小生成树 + 树链剖分)
- UVA - 11354 Bond(生成树+LCA)
- UVA 11354Bond(MST+LCA)
- PHP学习路线图
- iOS面试题系列之Objective-C相关
- README
- ios本地文件内容读取,.json .plist 文件读写
- 数据库优化——MySQL权限与安全
- Bond UVA
- static.abstract.synchronized
- 前端用的部分技术点(一)
- 混合中文+括号的正则表达式
- PHP程序员要想在北京买房你得狠
- iOS Block使用
- Gas Station
- 【R语言爬虫】网贷天眼数据平台表格数据抓取2
- OpenGL蓝宝书源码学习(三)第三章——GeoTest.cpp