题目描述

A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

输入输出格式

输入格式:

输入文件名为 truck.in。

输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道

路。 接下来 m 行每行 3 个整数 x、 y、 z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意: x 不等于 y,两座城市之间可能有多条道路 。

接下来一行有一个整数 q,表示有 q 辆货车需要运货。

接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。

输出格式:

输出文件名为 truck.out。

输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货

车不能到达目的地,输出-1。

输入输出样例

输入样例#1:

4 3

1 2 4

2 3 3

3 1 1

3

1 3

1 4

1 3

输出样例#1:

3

-1

3

嗯,感觉是很好的一道题qwq

思路:要求的是两点间所有路径中 满足 路径中的最小权值最大的一个权值

那么连点间权值较小的边完全可以舍弃(对答案无用),所以可以建一棵最大生成树,之后寻找两点的lca(显然选择lca答案最优),再求出路径 x—>lca(x,y)—>y 中所有边的最小权值就是答案

出错(决定以后把自己第一次写的代码哪里有问题记录下来qwq):

将两点间的最小权值求成某一点其子树中的最小权值

是不是很蠢?QAQ

code:

//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std; const int MAX=10010;
const int INF=0x3f3f3f3f;
int n,m,cnt;
int head[MAX],fa[MAX],dep[MAX],f[MAX][30],tree[MAX],fad[MAX]; int rd() { //快读
int x=0;
char c=' ';
while(c==' ' || c=='\n') c=getchar();
while(c<='9'&&c>='0') {
x=x*10+c-'0';
c=getchar();
}
return x;
} struct edges{
int from,to,next,con;
void add(int x,int y,int z) {//感觉这样建邻接表舒服233
to=y,from=x,con=z,next=head[x],head[x]=cnt;
}
void print() {//中间输出用
printf("from=%d to=%d next=%d con=%d",from,to,next,con);
}
}edge[MAX*10],tr[MAX*2]; bool cmp(edges x,edges y) {
return x.con>y.con;
} int get(int x) { //并查集
return fa[x]==x?x:fa[x]=get(fa[x]);
} void dfs(int u) { //dfs 得到每个点深度 父亲 及到父亲的边的权值
int mi=INF;
for(int i=head[u];i;i=tr[i].next) {
int v=tr[i].to;
// cout<<v<<":"<<f[u][0]<<endl;
if(v!=f[u][0]) {
dep[v]=dep[u]+1;//深度
f[v][0]=u;//父亲
fad[v]=tr[i].con;//记录边权
dfs(v);
}
}
} int getm(int u,int aim) { //求出路径中的最小权值
int mi=INF;
while(u!=aim) {
mi=min(mi,fad[u]);
u=f[u][0];
}
return mi;
} int lca(int x,int y) { //倍增lca
int a=x,b=y;
if(dep[x]<dep[y]) swap(x,y);
int d=dep[x]-dep[y];
for(int i=0;d;d>>=1,i++)
if(d&1) x=f[x][i];
if(x!=y) {
for(int i=20;i>=0;i--)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
x=f[x][0];
}
return min(getm(a,x),getm(b,x)); //输出整个路径边权最小值
} void init() { //倍增lca 预处理
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)
if(f[i][j-1]!=-1)
f[i][j]=f[f[i][j-1]][j-1];
} int main() {
n=rd(),m=rd();
for(int i=1;i<=m;i++) {
int a=rd(),b=rd(),c=rd();
edge[++cnt].add(a,b,c);
edge[++cnt].add(b,a,c);
}
sort(edge+1,edge+1+cnt,cmp); // for(int i=1;i<=cnt;i++) {
// cout<<i<<"-";edge[i].print();cout<<endl;
// }
// cout<<endl; for(int i=1;i<=n;i++) fa[i]=i;
memset(head,0,sizeof head);//预处理 int CNT=cnt;cnt=0;
for(int i=1;i<=CNT;i++) {//建最大生成树 // cout<<i<<"-";edge[i].print();cout<<endl; int u=edge[i].from,v=edge[i].to;
u=get(u),v=get(v);
if(u!=v) {
fa[u]=v; int a=edge[i].from,b=edge[i].to,c=edge[i].con;
tr[++cnt].add(a,b,c);
tr[++cnt].add(b,a,c);
// cout<<cnt-1<<"-";tr[cnt-1].print();cout<<endl;
// cout<<cnt<<"-"; tr[cnt].print();cout<<endl;
}
}
f[1][0]=-1;
dfs(1);
init();
int q=rd();
while(q--) {
int x=rd(),y=rd();
if(get(x)!=get(y)) printf("-1\n");
//特判 当两点不在同一并查集中时(说明至少有一个不在生成树中)就说明连不到这个点
else printf("%d\n",lca(x,y));
}
return 0;
}

[洛谷 P1967] 货车运输 (最大生成树 lca)的更多相关文章

  1. 洛谷 P1967 货车运输 Label: 倍增LCA && 最小瓶颈路

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

  2. 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增

    倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...

  3. 洛谷 P1967 货车运输

    洛谷 P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在 ...

  4. 【杂题总汇】NOIP2013(洛谷P1967) 货车运输

    [洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...

  5. 洛谷P1967 货车运输

    题目描述 \(A\)国有\(n\)座城市,编号从\(1\)到\(n\),城市之间有\(m\)条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有\(q\)辆货车在运输货物, 司机们想知道每辆车在 ...

  6. 洛谷—— P1967 货车运输 || COGS——C 1439. [NOIP2013]货车运输

    https://www.luogu.org/problem/show?pid=1967#sub  ||  http://www.cogs.pro/cogs/problem/problem.php?pi ...

  7. 洛谷P1967货车运输——倍增LCA

    题目:https://www.luogu.org/problemnew/show/P1967 就是倍增LCA的裸题,注意一些细节即可. 代码如下: #include<iostream> # ...

  8. 洛谷 P1967 货车运输 LCA + 最小生成树

    两点之间边权最大值的最小值一定在图的最小生成树中取到. 求出最小生成树,进行倍增即可. Code: #include<cstdio> #include<algorithm> u ...

  9. 洛谷 P1967 货车运输(克鲁斯卡尔重构树)

    题目描述 AAA国有nn n座城市,编号从 11 1到n nn,城市之间有 mmm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qqq 辆货车在运输货物, 司机们想知道每辆车在不超过车 ...

随机推荐

  1. 洛谷——P1616 疯狂的采药

    https://www.luogu.org/problem/show?pid=1616#sub 题目背景 此题为NOIP2005普及组第三题的疯狂版. 题目描述 LiYuxiang是个天资聪颖的孩子, ...

  2. i386和x86-64区别通俗易懂版本(转)

    x86架构首度出现在1978年推出的Intel 8086中央处理器,它是从Intel 8008处理器中发展而来的,而8008则是发展自Intel 4004的.Intel之后又推出了包括80186.80 ...

  3. cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第六步--金币&amp;岩石加入而且管理

    说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

  4. android-PullRefreshLayout使用

    类似与谷歌的SwipeRefreshLayout.但比SwipeRefreshLayout美丽. 执行效果: 使用说明: 用法和SwipeRefreshLayout几乎相同. 在xml中: 1 2 3 ...

  5. Java图形界面(GUI)——如何将JTable成功放入面板

    在这次课程设计中,大部分内容都设计的很流畅,没有遇到太大的问题,但在面板中加入JTable时确实花费了一部分时间,在此将解决办法总结出来: 定义控件: JPanel panel = new JPane ...

  6. 关于PHP浮点数之 intval((0.1+0.7)*10) 为什么是7

    PHP是一种弱类型语言, 这样的特性, 必然要求有无缝透明的隐式类型转换, PHP内部使用zval来保存任意类型的数值, zval的结构如下(5.2为例): struct _zval_struct { ...

  7. get post 的区别

    比较 GET 与 POST 还有一个问题就是:form 表单的get post 的默认传输量是多少? 期待评论区来解答!!! 一个获取数据,一个修改数据. 下面的表格比较了两种 HTTP 方法:GET ...

  8. 【BZOJ1196】【HNOI2006】公路修建问题

    [描述] OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织成立了,旨在建 ...

  9. centos6.5 + Nat网络模式 +SecureCRT 的相关设置

    步骤1:先去查看子网掩码和子网ip 提示:打开后先不要关闭,后边还会使用 步骤2:查看本机名 输入: hostname 步骤3:修改本机名 vi /etc/sysconfig/network 在”Ho ...

  10. jbox如果弹不出,放在body里

    body> <form id="form1" runat="server"> <script type="text/javas ...