The Subtle Balloons Company (SBC) is the main balloon provider for programming contests; it has
huge factories and warehouses, as well as an extensive truck
eet to ensure the contestants' happiness.
There are lots of competition sites in Nlogonia, and all of them hired SBC for supplying balloons for
their contests. Nlogonia is an archipelago connected by several bridges. Every island of Nlogonia may
have several regional sites and may also house several SBC warehouses.
When planning the routes for balloon deliveries, SBC faced a problem: for safety issues, every
bridge in Nlogonia has some maximum weight limit for vehicles which cross it. And because of the
great net weight of the transported merchandise, SBC operations' chief asked you to write a program to
determine the maximum weight allowed to be transported between warehouses and competition sites.
Input
The input contains several test cases. The rst line of a test case contains three integers N, M and S
which indicate, respectively, the number of islands, the number of bridges that connect the islands and
the number of sites. The islands are numbered from 1 to N.
Each of the next M lines describes a bridge. The description of a bridge consists in a line with
three integers A, B and W, indicating respectively the two islands connected by the bridge and the
maximum weight allowed in that bridge, in tons.
All bridges are two-way roads; every pair of islands is connected by at most one bridge; and it is
possible to reach every other island in the archipelago using only bridges (naturally it may be needed
to pass through other islands to do so).
Each of the next S lines describe a competition site and contains two integers L and H indicat-
ing, respectively, the number of the island where this site is and the number of the island where the
wharehouse which will be used to deliver the balloons to the site is.
Output
For each site in a test case, in the order they were given, your program must produce a single line,
containing a single integer, the biggest weight which can be transported by truck from the warehouse
to the site.
Restrictions

• 2 ≤ N ≤ 2 × 104
• 1 ≤ M ≤ 105
• 1 ≤ S ≤ 5 × 104
• 1 ≤ A, B, L, H ≤ N, A ̸= B, L ̸= H
• 0 ≤ W ≤ 105

Sample Input
4 5 4
1 2 9
1 3 0
2 3 8
2 4 7
3 4 4
1 4
2 1
3 1
4 3
4 5 2
1 2 30
2 3 20
3 4 10
4 1 40
2 4 50
1 3
1 2

Sample Output
7
9
8
7
20
40

1: 如果(u,v)为轻边,则size(v)<=size(u)/2;

2: 从根到某一点的路径上轻边的个数不大于O(logN)

时间复杂度O(N*logN*logN)

树链剖分:

view code#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
const int INF = 1<<30;
const int M = 200010;
const int N = 20010;
int n, m, Q;
int pre[N], sz[N], fa[N], top[N], id[N], fid[N];
int dep[N], gid, son[N];
int Min[N<<2]; struct edge
{
int u, v, w, next;
bool operator < (const edge &o)const{
return w>o.w;
}
edge(int u, int v, int w):u(u),v(v),w(w) {}
edge() {}
edge(int u, int v, int w, int next):u(u),v(v),w(w),next(next) {}
}e[M], mst[M];
int mcnt; void addedge(int u, int v, int w)
{
mst[mcnt] = edge(u, v, w, pre[u]);
pre[u] = mcnt++;
mst[mcnt] = edge(v, u, w, pre[v]);
pre[v] = mcnt++;
} int find(int x)
{
return x==fa[x]?x:(fa[x]=find(fa[x]));
} void MST()
{
mcnt = 0;
for(int i=0; i<=n; i++) fa[i] = i;
memset(pre, -1, sizeof(pre));
sort(e, e+m);
for(int i=0; i<m; i++)
{
int u = find(e[i].u), v = find(e[i].v);
if(u==v) continue;
// printf("(%d, %d) ->%d\n", e[i].u, e[i].v, e[i].w);
fa[u] = v;
addedge(e[i].u, e[i].v, e[i].w);
}
} void dfs(int u, int f, int d)
{
// fa[u]表示u的父亲,dep[u]表示u的深度
//sz[u]表示u字节点的个数
//son[u]与u在同重链上的儿子节点
fa[u] = f; dep[u] = d; son[u] = 0; sz[u] = 1;
for(int i=pre[u]; ~i; i=mst[i].next)
{
int v = mst[i].v;
if(v==f) continue;
dfs(v, u, d+1);
sz[u] += sz[v];
if(sz[son[u]] < sz[v]) son[u] = v;
}
} void get_pos(int u, int f)
{
//id[u]表示u与其父亲节点的连边,在线段树中的位置
id[u] = ++gid;
fid[gid] = u;//fid与id数组相反,在这道题没什么用
top[u] = f;//top[u] 表示u所在的重链的顶端节点
if(son[u]!=0) get_pos(son[u], f);
for(int i=pre[u]; ~i; i=mst[i].next)
{
int v = mst[i].v;
if(v==fa[u] || v==son[u]) continue;
get_pos(v, v);
}
} void build(int l, int r, int rt)
{
if(l==r){
Min[rt] = INF;
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
} void update(int p, int c, int l, int r, int rt)
{
if(l==r){
Min[rt] = c;
return ;
}
int m = (l+r)>>1;
if(p<=m) update(p, c, lson);
else update(p, c, rson);
Min[rt] = min(Min[rt<<1], Min[rt<<1|1]);
} int query(int L, int R, int l ,int r, int rt)
{
if(L<=l && R>=r) return Min[rt];
int m = (l+r)>>1, ans = INF;
if(L<=m) ans = min(ans, query(L,R,lson));
if(R>m) ans = min(ans, query(L,R,rson));
return ans;
} int lca(int u, int v)
{
int fv = top[v], fu = top[u];
int ans = INF;
while(fv!=fu)
{
if(dep[fv]>dep[fu])
{
swap(fv, fu); swap(u,v);
}
ans = min(ans, query(id[fu], id[u], 1, gid, 1));
u = fa[fu];
fu = top[u];
}
if(dep[u]<dep[v]) swap(u, v);
if(u!=v) ans = min(ans, query(id[v]+1, id[u], 1, gid, 1));//ti[v]指的是v与其父亲的边,所以+1
return ans;
} int main()
{
// freopen("in.txt", "r", stdin);
while(scanf("%d%d%d", &n, &m, &Q)>0)
{
for(int i=0; i<m; i++)
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
MST();
sz[1] = 0, gid = 0;
dfs(1, 1, 1);
get_pos(1, 1);
build(1, gid, 1);
int u, v;
for(int i=0; i<mcnt; i++)
{
int u = mst[i].u, v = mst[i].v;
if(dep[u]<dep[v]) swap(u,v);
update(id[u], mst[i].w, 1, gid, 1);
}
while(Q--)
{
scanf("%d%d", &u, &v);
printf("%d\n", lca(u,v));
}
}
return 0;
}

uva 12655 Trucks [LCA](树链剖分+MST)的更多相关文章

  1. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)

    Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...

  2. [BZOJ3626] [LNOI2014]LCA(树链剖分)

    [BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...

  3. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  4. Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分

    D. Happy Tree Party     Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...

  5. BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )

    说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...

  6. [CodeVS2370] 小机房的树 (LCA, 树链剖分, LCT)

    Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花 ...

  7. BZOJ3626[LNOI2014]LCA——树链剖分+线段树

    题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...

  8. bzoj 3626 : [LNOI2014]LCA (树链剖分+线段树)

    Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q ...

  9. LCA树链剖分

    LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LC ...

随机推荐

  1. C#中Guid类型值如何判断不是初始值!

    示例: public Guid _CurrentApplayInfoID { get; set; } 如何判断不是初始值"00000000-0000-0000-0000-0000000000 ...

  2. RSA密钥——JAVA与C#的区别和联系

    PS:好久没写博了,最近在考虑以后的事情,而且手上杂事也比较多,终于得空来写两篇.   首先感谢:http://www.codeproject.com/Articles/25487/Cryptogra ...

  3. 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout

    [源码下载] 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout 作者:webabcd 介绍重新想象 ...

  4. Python: Convert rst to html

    pip install sphinx rst2html.py in_file.rst out_file.html

  5. 两种设计模式(2)==>>"单例"

    所谓“单例”: 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资 ...

  6. ahjesus Unity3D XML注释被编译的问题

    public class XMLStringReader : MonoBehaviour { public string slectedItem; private bool editing = fal ...

  7. ThoughtWorks.QRCode生成二维码

    首先引用需要的dll,此处使用的是ThoughtWorks.QRCode.dll,网上可以找到对应的,此处也有一份,点击下载 http://files.cnblogs.com/files/ives/T ...

  8. xscript脚本

    最近看<游戏脚本高级编程>,然后顺便把里面实现的虚拟机,汇编器以及编译器手动用C++重写了一遍,原版书中提供的代码,风格不是很好,而且有几处BUG.我现在开源的代码中已经修复了BUG,而且 ...

  9. viewport的一些事

    整理了下viewport的东西,用脑图画了下

  10. ASP.NET MVC 微信公共平台开发之验证消息的真实性

    ASP.NET MVC 微信公共平台开发 验证消息的真实性 在MVC Controller所在项目中添加过滤器,在过滤器中重写 public override void OnActionExecuti ...