UVA 11354Bond(MST+LCA)
来源:互联网 发布:淘宝上新速度 编辑:程序博客网 时间:2024/04/30 21:54
题意:
给定N≤5×104,M≤105的图,Q≤5×104次询问
(u,v)找到一条路径使得最大边权最小
分析:
找最小,显然先搞一遍MST
求(u,v)树上2点间的最大边,倍增搞一下就可以了,当然树剖也是可以的
代码:
//// Created by TaoSama on 2015-11-09// Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << " "#define prln(x) cout << #x << " = " << x << endlconst int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;int n, m, q;struct RawEdge { int u, v, c; bool operator<(const RawEdge& rhs) const { return c < rhs.c; }};vector<RawEdge> E;struct Edge { int v, c, nxt;} edge[N];int head[N], cnt;void add_edge(int u, int v, int c) { edge[cnt] = (Edge) {v, c, head[u]}; head[u] = cnt++;}int par[N];int find(int x) { return par[x] = par[x] == x ? x : find(par[x]);}void kruskal() { for(int i = 1; i <= n; ++i) par[i] = i; sort(E.begin(), E.end()); cnt = 0; memset(head, -1, sizeof head); int num = 0; for(auto &e : E) { int u = find(e.u), v = find(e.v); if(u == v) continue; par[u] = v;// pr(e.u); pr(e.v); prln(e.c); add_edge(e.u, e.v, e.c); add_edge(e.v, e.u, e.c); if(++num == n - 1) break; }}int dep[N], p[20][N], maxv[20][N];void dfs(int u, int f, int c, int d) { dep[u] = d; p[0][u] = f; maxv[0][u] = c; for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(v == f) continue; dfs(v, u, edge[i].c, d + 1); }}void build() { dfs(1, -1, 0, 0); for(int i = 0; i + 1 < 18; ++i) { for(int v = 1; v <= n; ++v) { if(p[i][v] < 0) p[i + 1][v] = -1; else p[i + 1][v] = p[i][p[i][v]]; maxv[i + 1][v] = max(maxv[i][v], maxv[i][p[i][v]]); } }}int lca(int u, int v) { if(dep[u] > dep[v]) swap(u, v); for(int i = 0; i < 18; ++i) if(dep[v] - dep[u] >> i & 1) v = p[i][v]; if(u == v) return u; for(int i = 17; ~i; --i) if(p[i][u] != p[i][v]) u = p[i][u], v = p[i][v]; return p[0][u];}int get(int u, int to) { int ret = 0; for(int i = 0; i < 18; ++i) if(dep[u] - dep[to] >> i & 1) ret = max(ret, maxv[i][u]), u = p[i][u]; return ret;}int main() {#ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif ios_base::sync_with_stdio(0); int kase = 0; while(scanf("%d%d", &n, &m) == 2) { E.clear(); while(m--) { int u, v, c; scanf("%d%d%d", &u, &v, &c); E.push_back((RawEdge) {u, v, c}); } kruskal(); build(); scanf("%d", &q); if(kase++) puts(""); while(q--) { int u, v; scanf("%d%d", &u, &v); int _lca = lca(u, v);// prln(_lca); printf("%d\n", max(get(u, _lca), get(v, _lca))); } } return 0;}
0 0
- UVA 11354 Bond(MST + LCA)
- UVA 11354Bond(MST+LCA)
- UVA 11354 Bond (MST + LCA)
- UVA 11354 Bond(MST+LCA/二进制优化)
- UVA 11354 Bond (LCA + MST) (堆优化的Prim)
- UVa 11354 Bond (MST 树链剖分 LCA/RMQ)
- UVA 11354 Bond(MST+倍增)
- UVA 11354 Bond(最小生成树+LCA)
- Uva 11354 Bond(最小生成树+LCA)
- UVA 11354 Bond(prim+LCA,4级)
- UVA - 11354 Bond(生成树+LCA)
- 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倍增
- UVA 11354 - Bond(树链剖分)
- Android之PreferenceFragment的使用:
- CentOS6.5下Tomcat搭建Solr5.4.0集群
- pb
- Java 日期处理 Date 、Calendar 和TimeZone类
- 实用代码
- UVA 11354Bond(MST+LCA)
- react native Image 控件显示图片方式总结
- 8 线程、死锁
- CentOs 关机注意事项
- Angular $q 完全指南
- JavaEE命名服务与JNDI
- 在linux环境上如何部署SolrCloud
- QT backgound-image 与 bord-image
- iotjs移植到openwrt