UVA 11354 Bond (LCA + MST) (堆优化的Prim)
来源:互联网 发布:windows资源管理器黑屏 编辑:程序博客网 时间:2024/05/17 22:18
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=54643#problem/G
题意:n个点m条无向边相连,每条道路都有一个危险系数,对于q个询问,每个询问都包含一个起点s和终点t的路,使得途径所有边最大危险系数最小
思路:题目要求瓶颈路,但由于需要快速回答询问,所以需要做成易于查询的结构。先求MST,然后改为有根树,并利用类似LCA的办法,通过预处理计算anc和maxcost数组,其中anc[i][j]表示结点i的第2^j级祖先的编号,max[i][j]表示结点i和它的2^j级祖先之间的路径上的最大权值. 预处理后,我们对于每次查询的两个结点p, q,可以先把p和q提升到同一级的位置,让后利用类似二进制展开的方法不断把p和q同时往上“提”,并且更新最大边权
#include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <map>#include <set>#include <queue>#include <stack>#include <bitset>#include <functional>#include <utility>using namespace std;const int maxn = 100010;const int maxm = 200020;const int inf = 0x3f3f3f3f;int n, m;int fa[maxn], cost[maxn], h[maxn];int anc[maxn][20];int mcost[maxn][20];struct edge{ int from, to, w, nxt; edge() {} edge(int from, int to, int w) : from(from), to(to), w(w) {} bool operator < (const edge & rhs) const { return w > rhs.w; }};struct Prim{ int head[maxn], dis[maxn], vis[maxn]; int dep[maxn], pre[maxn], cnt; int n, sum; edge e[maxm]; void init(int n) { this -> n = n; cnt = 0; sum = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w) { e[cnt].from = u; e[cnt].to = v; e[cnt].w = w; e[cnt].nxt = head[u]; head[u] = cnt++; } void prim(int s) { priority_queue <edge> que; memset(dis, inf, sizeof(dis)); memset(vis, 0, sizeof(vis)); memset(dep, 0, sizeof(dep)); memset(pre, -1, sizeof(pre)); vis[s] = 1; dis[s] = 0; for(int i = head[s]; ~i; i = e[i].nxt) { int v = e[i].to; dis[v] = e[i].w; que.push(edge(s, v, e[i].w)); } while(!que.empty()) { edge now = que.top(); que.pop(); int u = now.to; if(vis[u]) continue; vis[u] = 1; pre[u] = now.from; dep[u] = dep[now.from] + 1; dis[u] = now.w; sum += now.w; for(int i = head[u]; ~i; i = e[i].nxt) { int v = e[i].to; int w = e[i].w; if(!vis[v] && dis[v] > w) { dis[v] = e[i].w; que.push(edge(u, v, w)); } } } }} mst;void preprocess(){ for (int i = 1; i <= n; i++) { anc[i][0] = fa[i]; mcost[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]; mcost[i][j] = max(mcost[i][j - 1], mcost[a][j - 1]); } } }}int query(int p, int q){ int log; if (h[p] < h[q]) swap(p, q); for (log = 1; (1 << log) <= h[p]; log++); log--; int ans = -inf; for (int i = log; i >= 0; i--) { if (h[p] - (1 << i) >= h[q]) { ans = max(ans, mcost[p][i]); p = anc[p][i]; } } if (p == q) return ans; for (int i = log; i >= 0; i--) { if (anc[p][i] != -1 && anc[p][i] != anc[q][i]) { ans = max(ans, mcost[p][i]); p = anc[p][i]; ans = max(ans, mcost[q][i]); q = anc[q][i]; } } ans = max(ans, max(cost[p], cost[q])); return ans;}int main(){ int ca = 0; while(~scanf("%d%d", &n, &m)) { if(ca++) putchar('\n'); mst.init(n); for(int i = 0; i < m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); mst.add(u, v, w); mst.add(v, u, w); } mst.prim(1);// cout << mst.sum << endl; for(int i = 1; i <= n; i++) { fa[i] = mst.pre[i]; cost[i] = mst.dis[i]; h[i] = mst.dep[i];// printf("%d %d %d\n", fa[i], cost[i], h[i]); } preprocess(); int q; scanf("%d", &q); while(q--) { int x, y; scanf("%d%d", &x, &y); printf("%d\n", query(x, y)); } } return 0;}
0 0
- UVA 11354 Bond (LCA + MST) (堆优化的Prim)
- UVA 11354 Bond(MST+LCA/二进制优化)
- UVA 11354 Bond(MST + LCA)
- UVA 11354Bond(MST+LCA)
- UVA 11354 Bond (MST + LCA)
- UVa 11354 Bond (MST 树链剖分 LCA/RMQ)
- UVA 11354 Bond(prim+LCA,4级)
- UVA 11354 Bond(MST+倍增)
- UVA 11354 Bond(最小生成树+LCA)
- Uva 11354 Bond(最小生成树+LCA)
- UVA - 11354 Bond(生成树+LCA)
- Prim 的堆优化
- uva 12655 Trucks [LCA](树链剖分+MST)
- UVA 11354 - Bond 最小树/LCA/瓶颈路
- 【UVa】11354 Bond 最小生成树,动态LCA,倍增思想
- UVA 11354 Bond 瓶颈路 最小生成树+LCA类似
- UVA 11354 Bond(最小生成树+LCA倍增)
- UVa 11354 Bond 最小生成树+LCA倍增
- Hbase 查询为什么快
- rk3128 camera sensor的注册
- spring学习之@ModelAttribute运用详解
- Convolutional Networks for Images,Speech,and Time-series
- Google图片搜索的原理
- UVA 11354 Bond (LCA + MST) (堆优化的Prim)
- 在Linux下安装kaldi工具箱
- iOS 7开源项目干货集合
- <读书笔记>新手菜鸟1号—《数据挖掘基础教程》-1
- (四)(1)揭开ZigBee 2006协议栈Z-Stack的”开源“面纱及其他彻底开源的zigbee协议
- 修改teamviewer id
- [Hadoop]Google 的Protocol Buffers 入门
- Android实现基于TCP和UDP协议的即时通讯,含android端和服务器端
- 快速排序