codevs3287货车运输(最小生成树+LCA)
3287 货车运输
2013年NOIP全国联赛提高组
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
3
-1
3
对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q < 1,000;
对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q < 1,000;
对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。
/*
先跑最小生成树找到那些尽量大的边,
然后LCA维护两点间最小载重就好了。
至于-1的情况嘛 如果建完图后不在图里的自然就到不了了
怎么算是不在图里呢 深度为0且不是树根(1)。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define maxn 1000000 using namespace std;
int n,m,q,x,y,num,cnt,a,b,c,k,tmp;
int deep[maxn],head[maxn],fa[maxn];
int f[][],dis[][];
struct node
{
int from;
int to;
int dis;
int next;
};
node e[maxn*],p[maxn*]; void add(int from,int to,int dis)
{
e[++num].from=from;
e[num].to=to;
e[num].dis=dis;
e[num].next=head[from];
head[from]=num;
} bool cmp(node x,node y)
{
return x.dis>y.dis;
} int find(int x)
{
if(x==fa[x])return x;
else return fa[x]=find(fa[x]);
} void Kruskal()
{
for(int i=;i<=n;i++)
fa[i]=i;
sort(p+,p+m+,cmp);
for(int i=;i<=m;i++)
{
int r1=find(p[i].from);
int r2=find(p[i].to);
if(r1!=r2)
{
fa[r2]=r1;
add(p[i].from,p[i].to,p[i].dis);
add(p[i].to,p[i].from,p[i].dis);
k++;
}
if(k==n-) break;
}
} void DFS(int now,int from,int c,int Dis)
{
f[now][]=from;deep[now]=c;
dis[now][]=Dis;
for(int i=head[now];i;i=e[i].next)
{
if(e[i].to!=from)
DFS(e[i].to,now,c+,e[i].dis);
}
} void get_fa()
{
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
{
f[i][j]=f[f[i][j-]][j-];
dis[i][j]=min(dis[i][j],dis[f[i][j-]][j-]);
dis[i][j]=min(dis[i][j],dis[i][j-]);
}
} int get_same(int a,int t)
{
for(int i=;i<;i++)
{
if(t&(<<i))
{
tmp=min(tmp,dis[a][i]);
a=f[a][i];
}
}
return a;
} int LCA_query(int a,int b)
{
if(a!=&&deep[a]==) return -;
if(b!=&&deep[b]==) return -;
tmp=0x3f3f3f3f;
if(deep[a]<deep[b]) swap(a,b);
a=get_same(a,deep[a]-deep[b]);
if(a==b) return tmp;
else
{
for(int i=;i>=;i--)
{
if(f[a][i]!=f[b][i])
{
tmp=min(tmp,dis[a][i]);
tmp=min(tmp,dis[b][i]);
a=f[a][i];
b=f[b][i];
}
}
tmp=min(tmp,dis[a][]);
tmp=min(tmp,dis[b][]);
}
return tmp;
} int main()
{
memset(dis,/,sizeof dis);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
p[i].from=a;
p[i].to=b;
p[i].dis=c;
}
Kruskal();
DFS(,,,);dis[][]=0x3f3f3f3f;
get_fa();
scanf("%d",&q);
for(int i=;i<=q;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA_query(x,y));
}
return ;
}
codevs3287货车运输(最小生成树+LCA)的更多相关文章
- C++之路进阶——codevs3287(货车运输)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n ...
- 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...
- 【NOIP2013/Codevs3287】货车运输-最小生成树(大)-树上倍增
https://www.luogu.org/problemnew/show/P1967 由题可知,我们走的路的边应尽可能大,所以通过kruscal建最大生成树的图,再树上倍增,注意可能有多棵树; #i ...
- P1967 货车运输[生成树+LCA]
题目描述 A国有n座城市,编号从 1到n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q* 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重 ...
- 货车运输(LCA+最大生成树)
神奇传送门 恩,这是一道神奇的LCA+难度的题目. 题目是这样的: A 国有n座城市,编号从1到n,城市之间有 m条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q辆货车在运输货物,司机们 ...
- P1967 货车运输【LCA】【生成树】
题目描述 A 国有 nn 座城市,编号从 11 到 nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重. 现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的 ...
- [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增
Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...
- 【题解】洛谷P1967 [NOIP2013TG] 货车运输(LCA+kruscal重构树)
洛谷P1967:https://www.luogu.org/problemnew/show/P1967 思路 感觉2013年D1T3并不是非常难 但是蒟蒻还是WA了一次 从题目描述中看出每个点之间有许 ...
- 洛谷P1967货车运输——倍增LCA
题目:https://www.luogu.org/problemnew/show/P1967 就是倍增LCA的裸题,注意一些细节即可. 代码如下: #include<iostream> # ...
随机推荐
- Luogu P2176 [USACO14FEB]路障Roadblock
解题思路 这是一道最短路题目,不知道大家有没有做过玛丽卡这道题目,如果没做,在做完这道题之后可以去拿个双倍经验哦 先求出一张图中的最短路径,并将其记录下来,我们首先思考:要有增量的前提是新的最短路径比 ...
- [Algorithm] 10. Reverse Integer
Description Given a 32-bit signed integer, reverse digits of an integer. Example Example 1: Input: 1 ...
- MySQL数据库开启、关闭、查看函数功能的方法
应用 MySQL 时,会遇到不能创建函数的情况.出现如下错误信息: ERROR 1418 : This function has none of DETERMINISTIC, NO SQL, or R ...
- python_ 学习笔记(基础语法)
python的注释 使用(#)对单行注释 使用('''或者""")多行注释,下面的代码肯定了python的牛逼 print("python是世界上最好的语言吗? ...
- Spring MVC概述(2)
1.Spring 为展现层提供基于MVC设计理念的优秀的Web框架,是目前最主流的MVC框架之一. 2.Spring 3.0后全面超越Struts2,成为最优秀的MVC框架. 3.Spring MVC ...
- Java基础学习总结(86)——Java异常处理机制Exception抛出异常时throw和throws用法详解
什么时运行时异常?什么是非运行时异常? 通俗的讲: 运行时异常:就是编译通过,运行时就崩了,比如数组越界. 非运行时异常:就是编译不通过,这时就得必须去处理了.不然就没法运行了. 全面的讲: Thro ...
- 【网络流24题】最长k可重区间集问题(费用流)
[网络流24题]最长k可重区间集问题 [问题分析] 最大权不相交路径问题,可以用最大费用最大流解决. [建模方法] 方法1 按左端点排序所有区间,把每个区间拆分看做两个顶点<i.a>< ...
- 使用C#执行PowerShell命令
按照网上的教程配置会发生SSL链接错误 该文章的最后使用了SSL来保证账户在连接服务器的时候不发生账户认证错误,但是我经过测试发现这个是不可行的,有一种更为简单的方法 首先要对服务器进行winrm设置 ...
- Cocos2d-x教程(34)-三维物体OBB碰撞检測算法
欢迎增加Cocos2d-x 交流群:193411763 个中心点.1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包括了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长). ...
- Solidworks如何整体缩放零件
比如我有一个飞机模型,当前长度有20000mm,即20M,我想要整体缩放 点击插入-特征-缩放比例 在左侧的框中输入所有要缩放的零部件(如果全部缩放,则全部框选所有零件,就可以把所有零件都放到 ...