UVa 11354 - Bond(最小生成树+倍增lca)
2017-10-11 18:35
519 查看
题目链接
简介:
最小瓶颈路,点对之间的路径中的最大边权
分析:
肯定是先求出最小生成树(一看到瓶颈路,就要往这方面想,当然也不是绝对的)
因为需要回答大量的查询,我们就需要把信息组织成某种易于查询的结构
一开始我认为可以直接像例一这样n^2处理,O(1)回答
但是n的范围不允许我这样干,
所以我们还是用最古老的方法:倍增
那么这道题就和货车运输有异曲同工之妙了
简介:
最小瓶颈路,点对之间的路径中的最大边权
分析:
肯定是先求出最小生成树(一看到瓶颈路,就要往这方面想,当然也不是绝对的)
因为需要回答大量的查询,我们就需要把信息组织成某种易于查询的结构
一开始我认为可以直接像例一这样n^2处理,O(1)回答
但是n的范围不允许我这样干,
所以我们还是用最古老的方法:倍增
那么这道题就和货车运输有异曲同工之妙了
tip
代码量有点大//这里写代码片 #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=50003; int n,m,q; int st ,tot=0,fa ,pre [20],deep ,maxx [20],lg; struct node{ int x,y,v; }; node e[N<<1]; struct node2{ int x,y,v,nxt; }; node2 way[N<<1]; int cmp(const node &a,const node &b){return a.v<b.v;} int find(int x) { if (fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } void unionn(int f1,int f2){fa[f1]=f2;} void add(int u,int w,int z) { tot++; way[tot].x=u;way[tot].y=w;way[tot].v=z;way[tot].nxt=st[u];st[u]=tot; } void Kruskal() { sort(e+1,e+1+m,cmp); int cnt=0; for (int i=1;i<=n;i++) fa[i]=i; for (int i=1;i<=m;i++) { int f1=find(e[i].x); int f2=find(e[i].y); if (f1!=f2) { unionn(f1,f2); add(e[i].x,e[i].y,e[i].v); add(e[i].y,e[i].x,e[i].v); cnt++; } if (cnt==n-1) break; } } void dfs(int now,int fa,int dep) { deep[now]=dep; pre[now][0]=fa; for (int i=st[now];i;i=way[i].nxt) if (way[i].y!=fa) { maxx[way[i].y][0]=way[i].v; //边权转移到靠下的点上 dfs(way[i].y,now,dep+1); } } void cl() { lg=log(n)/log(2)+1; for (int i=1;i<=lg;i++) for (int j=1;j<=n;j++) { pre[j][i]=pre[pre[j][i-1]][i-1]; maxx[j][i]=max(maxx[j][i-1],maxx[pre[j][i-1]][i-1]); } } int ask(int u,int w) { int ans=0; if (deep[u]<deep[w]) swap(u,w); int d=deep[u]-deep[w]; if (d) for (int i=0;i<=lg&&d;i++,d>>=1) if (d&1) ans=max(ans,maxx[u][i]),u=pre[u][i]; if (u==w) return ans; for (int i=lg;i>=0;i--) if (pre[u][i]!=pre[w][i]) { ans=max(ans,maxx[u][i]); ans=max(ans,maxx[w][i]); u=pre[u][i]; w=pre[w][i]; } ans=max(ans,maxx[u][0]); ans=max(ans,maxx[w][0]); return ans; } int main() { int cnt=0; while (scanf("%d%d",&n,&m)!=EOF) { if (cnt++) puts(""); memset(st,0,sizeof(st)); memset(pre,0,sizeof(pre)); memset(maxx,0,sizeof(maxx)); tot=0; for (int i=1;i<=m;i++) { int u,w,z; scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v); } Kruskal(); dfs(1,0,1); cl(); scanf("%d",&q); for (int i=1;i<=q;i++) { int u,w; scanf("%d%d",&u,&w); printf("%d\n",ask(u,w)); } } return 0; }
相关文章推荐
- 【UVa】11354 Bond 最小生成树,动态LCA,倍增思想
- UVA 11354 Bond(最小生成树+lca+倍增求祖先节点)
- UVa 11354 Bond 最小生成树+LCA倍增
- UVA 11354 Bond(最小生成树+LCA倍增)
- Uva 11354 Bond(最小生成树+LCA)
- UVA - 11354Bond最小生成树,LCA寻找最近公共祖先
- UVA 11354 Bond 瓶颈路 最小生成树+LCA类似
- UVA - 11354Bond最小生成树,LCA寻找近期公共祖先
- 【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)
- UVA 11354 Bond(最小生成树+LCA)
- UVA 11354 Bond(最小瓶颈路+倍增)
- UVA 11354 LCA+最小生成树
- uva 11354 bond 最小生成树
- UVA 11354 Bond (最小生成树 + 树链剖分)
- uva 11354最小生成树瓶颈路(lca算法实现)(rmq在多校二中有一道题)
- Kruskal,最小生成树,树链剖分,LCA(邦德,UVA 11354)
- UVA - 11354 Bond(生成树+LCA)
- UVA-11354-Bond(树上倍增,dp,MST,LCA)
- UVA11354[Bond] 倍增求LCA+Kruskal求最小瓶颈生成树
- UVA 11354 Bond(MST + LCA)