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. Django中media的配置

    Django中media的配置 Django中media文件夹是我们文件(比如头像.文件.视频等)数据十分重要的存放处,这里以用户头像的上传以及media文件的访问为例为大家详细讲解下media的相关 ...

  2. struts设置开发者模式

    struts设置开发者模式 在使用ssh框架做项目时,struts.xml文件总要配置许多项功能,其中一个就是开发者模式: <constant name="struts.devMode ...

  3. github 添加wiki

    亲们支持我的新博客哦==>地址(以后更新会尽量在新博客更新,欢迎大家访问加入我的后宫w) ) 平时都是写readMe和docs的,一直眼瞎没有注意到有wiki这个功能 随便找一个写了wiki的看 ...

  4. VS 代码片段集

    片段1:用于线程执行代码,耗时操作时加载Loging; <?xml version="1.0" encoding="utf-8"?> <Cod ...

  5. python3 kmp 字符串匹配

    先声明,本人菜鸟一个,写博客是为了记录学习的过程,以及自己的理解和心得,可能有的地方写的不好,希望大神指出... 抛出问题 给定一个文本串test_str(被匹配的字符串)和模式串pat_str(需要 ...

  6. 【Linux】【Jenkins】系统配置报反向代理设置有误问题的解决方案

    1.如图所示: 2.点击更多信息,查看解决办法: https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+says+my+reverse+proxy+s ...

  7. 【Linux】【Jenkins】代码编译和执行过程中的问题汇总

    1.问题1:java.io.FileNotFoundException: /root/.jenkins/workspace/Videoyi_AutoTest_Maven/config-log4j\lo ...

  8. js类的继承,es5和es6的方法

    存在的差异:1. 私有数据继承差异 es5:执行父级构造函数并且将this指向子级 es6:在构造函数内部执行super方法,系统会自动执行父级,并将this指向子级2. 共有数据(原型链方法)继承的 ...

  9. PyQt5系列教程(六)如何让界面和逻辑分离

    软硬件环境 OS X EI Capitan Python 3.5.1 PyQt 5.5.1 PyCharm 5.0.3 前言 前面的内容我们介绍了利用QtDesigner来设计界面,再通过命令行工具p ...

  10. uva-10602-贪心

    题意:有个编辑器,支持三种操作,摁下一个键盘上的字符,重复最后一个单词,删除最后一个字符.给N个字符串,必须先在编辑器内输入第一个字符, 问,输入完所有字符串最少需要摁下多少次键盘. 最多100个字符 ...