【CJOJ1090】【洛谷1967】【NOIP2013】货车运输
题面
Description
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
Input
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
Output
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。
Sample Input
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
Sample Output
3
-1
3
Hint
对于 30%的数据,0 < n <1,000,0 < m < 10,000,0 < q < 1,000;
对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。
题解
这道题方法很多很多,听说可以运用网络流、树链剖分等等等方法。
我用的方法适合我这种小蒟蒻
我们看看题目,要求的是给定的两对点之间的所有路径中,路径中最短的边的最大值。
这一类题目很容易想到构造 最大/最小生成树
我们可以证明这条路径必定在最大生成树上。
假设最大生成树上两点之间的路径的最小值为x
若存在另外一条路径,使得这两点之间的路径的最小值为x'
x'>x
那么,根据最小生成树建树的原理,x'这条路径必定会在x之间建出,
因此不可能存在不在最大生成树上的边可以使得答案更大。
那么,求出最大生成树之后,直接使用倍增LCA求解即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX 11000
#define MAXL 51000
#define INF 20000000
inline int read()
{
register int x=0,t=1;
register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-'){t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*t;
}
int f[MAX],dep[MAX];
int minl[MAX][15],p[MAX][51];
int n,m,Q,u,v,w;
struct Line
{
int u,v,w;//从u到v,权值w
}e[MAXL];
struct Edge
{
int v,next,w;
}E[MAXL];
int h[MAX],cnt=1,tot=1;
inline void Add(int u,int v,int w)//建边
{
E[tot]=(Edge){v,h[u],w};
h[u]=tot++;
}
inline bool operator <(Line a,Line b)//需要求最大生成树
{
return a.w>b.w;
}
int getf(int u)//并查集
{
return f[u]==u?u:f[u]=getf(f[u]);
}
void Build(int u,int ff)//建树
{
for(int i=h[u];i;i=E[i].next)
{
int v=E[i].v;
if(v!=ff)
{
dep[v]=dep[u]+1;
p[v][0]=u;
minl[v][0]=E[i].w;
Build(v,u);
}
}
}
void Prepare()//LCA的预处理
{
for(int j=1;(1<<j)<=n;++j)
{
for(int i=1;i<=n;++i)
{
p[i][j]=p[p[i][j-1]][j-1];
minl[i][j]=min(minl[i][j-1],minl[p[i][j-1]][j-1]);
}
}
}
int Query(int u,int v)//询问
{
int ans=INF;
if(dep[u]<dep[v])swap(u,v);//u是深度大的结点
for(int j=14;j>=0;--j)//使得u,v深度相同
if(p[u][j]&&dep[p[u][j]]>=dep[v])
{
ans=min(ans,minl[u][j]);
u=p[u][j];
}
if(u==v)
return ans;
for(int j=14;j>=0;--j)//找到LCA并求解
{
if(p[u][j]!=p[v][j])
{
ans=min(ans,minl[u][j]);
ans=min(ans,minl[v][j]);
u=p[u][j];
v=p[v][j];
}
}
ans=min(ans,minl[u][0]);
ans=min(ans,minl[v][0]);
return ans;
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
e[i]=(Line){read(),read(),read()};
sort(&e[1],&e[m+1]);
//克鲁斯卡尔求最大生成树
for(int i=1;i<=n;++i)f[i]=i;//并查集初始化
for(int i=1;i<n;++i)//克鲁斯卡尔
{
while(getf(e[cnt].u)==getf(e[cnt].v)&&cnt<=m)cnt++;//找到下一条可行的边
if(cnt>m)break;//不用连了,没有边了
f[getf(e[cnt].v)]=getf(e[cnt].u);//选择边
Add(e[cnt].u,e[cnt].v,e[cnt].w);
Add(e[cnt].v,e[cnt].u,e[cnt].w);
}
for(int i=1;i<=n;++i)//建树
if(!dep[i])
{
dep[i]=1;
Build(i,0);
}
Prepare();//LCA准备
Q=read();
while(Q--)
{
u=read();v=read();
if(getf(u)!=getf(v))//没有连在一起
printf("-1\n");
else
printf("%d\n",Query(u,v));
}
}
【CJOJ1090】【洛谷1967】【NOIP2013】货车运输的更多相关文章
- 【洛谷1967】货车运输(最大生成树+倍增LCA)
点此看题面 大致题意: 有\(n\)个城市和\(m\)条道路,每条道路有一个限重.多组询问,每次询问从\(x\)到\(y\)的最大载重为多少. 一个贪心的想法 首先,让我们来贪心一波. 由于要求最大载 ...
- [Luogu 1967] NOIP2013 货车运输
[Luogu 1967] NOIP2013 货车运输 一年多前令我十分头大的老题终于可以随手切掉了- 然而我这码风又变毒瘤了,我也很绝望. 看着一年前不带类不加空格不空行的清纯码风啊,时光也好像回去了 ...
- 【题解】【洛谷 P1967】 货车运输
目录 洛谷 P1967 货车运输 原题 题解 思路 代码 洛谷 P1967 货车运输 原题 题面请查看洛谷 P1967 货车运输. 题解 思路 根据题面,假设我们有一个普通的图: 作图工具:Graph ...
- 【题解】洛谷P1967 [NOIP2013TG] 货车运输(LCA+kruscal重构树)
洛谷P1967:https://www.luogu.org/problemnew/show/P1967 思路 感觉2013年D1T3并不是非常难 但是蒟蒻还是WA了一次 从题目描述中看出每个点之间有许 ...
- [洛谷P1967][题解]货车运输
题目 这道题让我们求最小限重的最大值 显然可以先求出最大生成树,然后在树上进行操作 因为如果两点之间有多条路径的话一定会走最大的,而其他小的路径是不会被走的 然后考虑求最小权值 可以采用倍增求LCA, ...
- NOIP2013 货车运输(最大生成树,倍增)
NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...
- 【洛谷P1967】[NOIP2013]货车运输
货车运输 题目链接 显然,从一点走到另一点的路径中,最小值最大的路径一定在它的最大生成树上 所以要先求出最大生成树,再在生成树上找最近公共祖先,同时求出最小值. #include<iostrea ...
- 洛谷P1967 [NOIP2013提高组Day1T2]货车运输
P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过 ...
- NOIp2013 货车运输 By cellur925
题目传送门 A 国有 n 座城市,编号从 1 到 n ,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重. 现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下 ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
随机推荐
- Maven服务器
Maven私服仓库管理: Nexus 3.0 使用nexus3.X搭建maven私服在Centos7环境中-详细教程
- TinyMce 使用初探
https://www.cnblogs.com/nkxyf/p/3883586.html 参考:http://www.tinymce.com/ 官网 http://www.tinymce.com ...
- mysql1 - 环境与体验
一.准备工作 1.mac 软件包管理工具:homebrew 2.brew 如何使用?命令行 输入: brew 3.mac 下如何查看 mysql 目录? find /usr/local/ -iname ...
- Linux CentOs集群LVS+Keepalived负载均衡的实现
准备工作 环境:Win10下Centos6.4虚拟机. 负载均衡:两台(一主一备) LVS + Keepalived. HTTP服务器:3台. 给每台服务器配置IP 1.VIP(virtual ip ...
- Spring data mongodb ObjectId ,根据id日期条件查询,省略@CreatedDate注解
先看看ObjectId 的json 结构,非常丰富,这里有唯一机器码,日期,时间戳等等,所以强烈建议ID 使用 ObjectId 类型,并且自带索引 Spring data mongodb 注解 @C ...
- init启动进程
init启动进程需要读取()配置文件 1,启动init进程的配置文件是/etc/inittab 2,/etc/sysvinit是系统初始化用的 /sbin/init在核心完整的加载后,开始运行系统 ...
- Zookeeper笔记二-各种一致性协议解释
我们知道Zookeeper的一致性是解决分布式事务的. 那么分布式事务代表的是强一致性. 强一致性解决的代表有以下协议(注意这几个协议跟zookeeper是没任何关系的,这是分布式的理论基础): 1. ...
- ubuntu10.04 安装配置tftp服务
tftpd-hpa 是一个功能增强的TFTP服务器.它提供了很多TFTP的增强功能,它已经被移植到大多数的现代UNIX系统. 1.安装 sudo apt-get install tftpd-hpa t ...
- tomcat证书配置
第一步:为服务器生成证书 1.进入%JAVA_HOME%/bin目录 2.使用keytool为Tomcat生成证书,假定目标机器的域名是"localhost",keystore文件 ...
- php simpleXML操作xml的用法
XML简介 XML是一种流行的半结构化文件格式,以一种类似数据库的格式存储数据.在实际应用中,一些简单的.安全性较低的数据往往使用 XML文件的格式进行存储.这样做的好处一方面可以通过减少与数据库的交 ...