https://www.luogu.org/problemnew/show/P1967

由题可知,我们走的路的边应尽可能大,所以通过$kruscal$建最大生成树的图,再树上倍增,注意可能有多棵树;

#include <bits/stdc++.h>
#define read read()
#define up(i,l,r) for(register int i = (l);i <= (r);i++)
#define down(i,l,r) for(register int i = (l);i >= (r);i--)
#define traversal_vedge(i) for(register int i = head[u]; i ;i = e[i].nxt)
#define ll long long
using namespace std;
int read
{
int x = , f = ; char ch = getchar();
while(ch < || ch > ) {if(ch == '-')f = -; ch = getchar();}
while(ch >= && ch <=) {x = * x + ch - ;ch = getchar();}
return x * f;
}
const int N = 1e4+,M = 5e5+,inf = 0x3f3f3f3f;
int n,m,q,f[N];
struct kedge{
int u,v,limit;
bool operator < (const kedge &x) const{
return limit > x.limit;
}
}ke[M<<]; struct edge{
int v,limit,nxt;
}e[M<<];int tot,head[N]; void build_tree(int u,int v,int w) {e[++tot] = (edge){v,w,head[u]}; head[u] = tot;} //-----------------------------------------------------------------
int find(int i) {if(f[i] == i) return i;f[i] = find(f[i]);return f[i]; }
void kruscal(){
sort(ke+,ke+m+);
up(i,,n) f[i] = i;
int cnt = ;
up(i,,m)
{
if(cnt == n-) break;
if(find(ke[i].u) != find(ke[i].v))
{
f[f[ke[i].u]] = f[ke[i].v];
cnt++;
build_tree(ke[i].u,ke[i].v,ke[i].limit);
build_tree(ke[i].v,ke[i].u,ke[i].limit);//debug ke[i].u -> ke[i].v;
}
else continue;
}
}
//----------------------------------------------------------------------- int fa[N][],mine[N][],dep[N],vis[N];//debug 15 ->14 void dfs(int u,int f,int w){
vis[u] = ;
dep[u] = dep[f] + ;
fa[u][] = f;
mine[u][] = w;
for(int i = ; (<<i) <= dep[u]; i++)
{
fa[u][i] = fa[fa[u][i-]][i-];
mine[u][i] = min(mine[u][i-],mine[fa[u][i-]][i-]);
}
traversal_vedge(i)
{
int v = e[i].v;
if(v == f) continue;
dfs(v,u,e[i].limit);
}
} /*int LCA(int x,int y){
if(dep[x] < dep[y]) swap(x,y);
down(i,14,0)
{
if(dep[fa[x][i]] >= dep[y])
x = fa[x][i];
}
if(x == y) return x;
down(i,14,0)
{
if(fa[x][i] != fa[y][i])
{
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][0];
}*/
//----------------------------------------------------------------- int query(int x,int y)
{
int ans = inf;
if(dep[x] < dep[y]) swap(x,y);
down(i,,)
{
if(dep[fa[x][i]] >= dep[y])
{
ans = min(ans,mine[x][i]);
x = fa[x][i];
}
}
if(x == y) return ans;
down(i,,)
{
if(fa[x][i] != fa[y][i])
{
ans = min(ans,min(mine[x][i],mine[y][i]));
x = fa[x][i];
y = fa[y][i];
}
}
ans = min(ans,min(mine[x][],mine[y][]));
return ans;
} /*int query(int x,int lca){
//if(x == lca) return 0x3f3f3f3f;
int i = 0;
while(dep[fa[x][i]] > dep[lca] ) i++;
return mine[x][i];
}*/ void work(){
kruscal();
memset(mine,0x3f,sizeof(mine));
//debug 未考虑多棵树
up(i,,n)
{
if(!vis[i])
dfs(i,,inf);
}
q = read;
while(q--)
{
int x = read, y = read;
if(find(x) != find(y))
{
printf("-1\n");
continue;
}
//int lca = LCA(x,y);
//ans = min(query(x,lca),query(y,lca));
printf("%d\n",query(x,y));
}
} void readdata()
{
n = read; m = read;
up(i,,m)
{
ke[i].u = read; ke[i].v = read; ke[i].limit = read;
}
} int main()
{
freopen("input21.txt","r",stdin);
//freopen("output21.out","w",stdout);
readdata();
work();
return ;
}

最开始的写法之所以是错误的,是因为会多求一段,而我们只需要求到LCA就行;

【NOIP2013/Codevs3287】货车运输-最小生成树(大)-树上倍增的更多相关文章

  1. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

  2. xsy 2018 【NOIP2013】货车运输

    [NOIP2013]货车运输 Description A 国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有q辆货车在运输货物,司机们想知道每辆车在不超 ...

  3. 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA

    题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...

  4. codevs3287货车运输(最小生成树+LCA)

    3287 货车运输 2013年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description A 国有 ...

  5. Luogu1967 NOIP2013 货车运输 最大生成树、倍增

    传送门 题意:给出一个$N$个节点.$M$条边的图,$Q$次询问,每一次询问两个点之间的所有可行路径中经过的边的边权的最小值中的最大值.$N \leq 10000 , M \leq 50000 , Q ...

  6. $Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$

    $Luogu$ $Sol$ 首先当然是构建一棵最大生成树,然后对于一辆货车的起点和终点倍增跑$lca$更新答案就好.记得预处理倍增的时候不仅要处理走了$2^i$步后是那个点,还有这中间经过的路径权值的 ...

  7. C++之路进阶——codevs3287(货车运输)

    3287 货车运输 2013年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description A 国有 n ...

  8. NOIP2013 D1T3 货车运输 zz耻辱记

    目录 先来证明下lemma: 图上2点间最小边权最大的路径一定在MST上 感性理解下: 每次kruskal algo都连接最大的不成环边 此时有2个未联通的联通块被连起来. 那么考虑u, v两点的联通 ...

  9. NOIP2013 D1T3 货车运输

    [NOIP2013T3]货车运输 背景 noip2013day1 描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重 量限制,简称限重.现在有 q 辆货 ...

随机推荐

  1. 源码:Java集合源码之:哈希表(二)

    要想知道一个元素是否在数组或链表中,只能从前向后挨个对比,无论是数组还是链表,其对数据的查询表现都比较无力.在的二叉排序树中,还会将数据排序以进行二分查找,将时间复杂度从O(n)降低到O(lg n). ...

  2. 204. jetcache:在Spring Boot中怎么玩?

      [视频&交流平台] àSpringBoot视频:http://t.cn/R3QepWG à SpringCloud视频:http://t.cn/R3QeRZc à Spring Boot源 ...

  3. dll 恐怖的代码调整

    总结一波这998的不得不提的调整代码的心得. 调整代码的背景:现有wps美化代码分散在各个插件里面,导致每次修改一小部分代码,都要全新编译,并且只能跟版本发,所以决定将wps的美化代码整合成一个插件d ...

  4. 59.纯 CSS 创作彩虹背景文字

    原文地址:https://segmentfault.com/a/1190000015352436 修改后地址:https://scrimba.com/c/cqK3LaTQ 感想: 又一次见识到CSS的 ...

  5. leetcode279

    动态规划 public class Solution { public int NumSquares(int n) { var list = new List<int>(); list.A ...

  6. LeetCode OJ 117. Populating Next Right Pointers in Each Node II

    题目 Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...

  7. java学习笔记(十):scanner输入

    可以通过 Scanner 类来获取用户的输入. 通过next()类和nextLine()类来获取字符串. 通过 Scanner 类的 next() 类来获取输入的字符串. import java.ut ...

  8. 20175314 实验一 Java开发环境的熟悉

    20175314 实验一 Java开发环境的熟悉 一.实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用IDEA 编辑.编译.运行.调试Java程序. 3.完成实验,撰写实验报告,注意实 ...

  9. Django的rest_framework认证组件之全局设置源码解析

    前言: 在我的上一篇博客我介绍了一下单独为某条url设置认证,但是如果我们想对所有的url设置认证,该怎么做呢?我们这篇博客就是给大家介绍一下在Rest_framework中如何实现全局的设置认证组件 ...

  10. mybatis多表关联

    1.比如我有两个一个是菜单表t_menu,一个是权限表t_jurisdiction.表结构如下: 2.我想要将这两个表关联,查询特定的role_id下的菜单情况,这也是我们经常用在权限管理系统中的做法 ...