题目:洛谷P1967、Vijos P1843、codevs3287。

题目大意:有n个城市m条道路,每条道路有一个限重,规定货车运货不能超过限重。有一些询问,问你两个城市之间一次最多能运多少重的货(可能无法到达)。

解题思路:首先,要保证原来连通的点连通,限重要尽可能大,所以最大生成树。然后对每个询问找两个点的最近公共祖先,然后求出两点路径上最大限重的最小值即可。

用倍增求LCA,可以边算边求出最小值,不用用一些复杂的方法。代码中我用sml[x][i]表示x和它的第$2^i$个祖先之间的路径上最大限重的最小值。然后在倍增时更新答案即可。详见代码

C++ Code:

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cstdio>
using std::sort;
using std::swap;
struct edge{
int u,v,t;
bool operator < (const edge& rhs)const{return t>rhs.t;}
}e[50005];
struct tree_edge{
int to,dist,nxt;
}E[120005];
int n,m,fa[10005],head[10005]={0},cnt=0,ans,deep[10005],p[10005][16],sml[10005][16];
inline int min(int a,int b){return(a<b)?(a):(b);}
inline int readint(){
char c=getchar();
int p=0;
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())p=(p<<3)+(p<<1)+(c^'0');
return p;
}
int dad(int x){return(fa[x]==x)?(x):(fa[x]=dad(fa[x]));}
inline int addedge(int from,int to,int dist){
E[++cnt]=(tree_edge){to,dist,head[from]};
head[from]=cnt;
E[++cnt]=(tree_edge){from,dist,head[to]};
head[to]=cnt;
}
void dfs(int u){
for(int i=head[u];i;i=E[i].nxt)
if(!deep[E[i].to]){
deep[E[i].to]=deep[u]+1;
p[E[i].to][0]=u;
sml[E[i].to][0]=E[i].dist;
dfs(E[i].to);
}
}
void init(){
for(int j=1;(1<<j)<=n;++j)
for(int i=1;i<=n;++i)
if(p[i][j-1]!=-1)
p[i][j]=p[p[i][j-1]][j-1],sml[i][j]=min(sml[i][j-1],sml[p[i][j-1]][j-1]);
}
int lca(int x,int y,int& ans){
ans=2000000000;
int i;
if(deep[x]<deep[y])swap(x,y);
for(i=0;(1<<i)<=n;++i);--i;
for(int j=i;j>=0;--j)
if(deep[p[x][j]]>=deep[y]){
ans=min(ans,sml[x][j]),x=p[x][j];
}
if(x==y)return x;
for(int j=i;j>=0;--j)
if(p[x][j]!=p[y][j]&&p[x][j]!=-1){
ans=min(ans,min(sml[x][j],sml[y][j]));
x=p[x][j];
y=p[y][j];
}
ans=min(ans,min(sml[x][0],sml[y][0]));
return p[x][0];
}
int main(){
n=readint(),m=readint();
for(int i=1;i<=m;++i)e[i].u=readint(),e[i].v=readint(),e[i].t=readint();
sort(e+1,e+m+1);
for(int i=1;i<=n;++i)fa[i]=i;
for(int okE=1,now=1;now<=m;++now){
int a=dad(e[now].u),b=dad(e[now].v);
if(a!=b){
fa[b]=a;
addedge(e[now].u,e[now].v,e[now].t);
++okE;
}
if(okE==n)break;
}
int Q=readint();
memset(deep,0,sizeof deep);
memset(p,-1,sizeof p);
memset(sml,0x3f,sizeof sml);
for(int i=1;i<=n;++i)
if(!deep[i]){
deep[i]=1;
dfs(i);
}
init();
while(Q--){
int x=readint(),y=readint();
int a=dad(x),b=dad(y);
if(a!=b){
puts("-1");
continue;
}
lca(x,y,ans);
printf("%d\n",ans);
}
}

[NOIP2013提高组]货车运输的更多相关文章

  1. [NOIP2013 提高组] 货车运输

    前言 使用算法:堆优化 \(prim\) , \(LCA\) . 题意 共有 \(n\) 个点,有 \(m\) 条边来连接这些点,每条边有权值.有 \(q\) 条类似于 \(u\) \(v\) 询问, ...

  2. [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路

    [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路 题目大意: 对于长度为\(n(n\le10^5)\)的非负数列\(A\),每次可以选取一个区间\(-1\).问将数列清零至少需要 ...

  3. [NOIP2013 提高组] 华容道 P1979 洛谷

    [NOIP2013 提高组] 华容道 P1979 洛谷 强烈推荐,更好的阅读体验 经典题目:spfa+bfs+转化 题目大意: 给出一个01网格图,和点坐标x,y空格坐标a,b,目标位置tx,ty要求 ...

  4. 【NOIP2013提高组】货车运输

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

  5. 洛谷P1967 [NOIP2013提高组Day1T2]货车运输

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

  6. [NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)

    一开始觉得是网络流..仔细一看应该是最短路,再看数据范围..呵呵不会写...这道题是最大生成树+最近公共祖先.第一次写..表示各种乱.. 因为要求运输货物质量最大,所以路径一定是在最大生成树上的.然后 ...

  7. NOIP2013 提高组 Day1

    https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=83%7C30 期望得分:100+100+100=300 实际得 ...

  8. 【NOIP2013提高组T3】加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  9. noip2013 提高组

    T1 转圈游戏 题目传送门 果不其然 第一题还是模拟题 一波快速幂解决问题 #include<cstdio> #include<cstring> #include<alg ...

随机推荐

  1. zookeeper的选举机制

    1)半数机制:集群中半数以上机器存活,集群可用.所以zookeeper适合装在奇数台机器上. 2)Zookeeper虽然在配置文件中并没有指定master和slave.但是,zookeeper工作时, ...

  2. BAT 解密(四):配置中心、服务中心、异步技术细节

    在系列文章的第二篇文章< BAT解密(二):聊聊业务如何驱动技术发展 >中我们深入分析了互联网业务发展的一个特点:复杂性越来越高.复杂性增加的典型现象就是系统越来越多,当系统的数量增加到一 ...

  3. 51nod-1503 猪和回文 - 二维矩阵上的dp

    题目链接 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有n行,m列组成.我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m.处于第r行第c列的格子用(r,c)表示. 刚开 ...

  4. exsi中的虚拟机添加磁盘后虚拟机中磁盘不出现

    exsi中的虚拟机添加磁盘后虚拟机中磁盘不出现解决: 计算机---> 管理: 这里可以选择磁盘,格式,分区, 改盘符等操作

  5. pagination使用说明

    参考自张鑫旭 准备工作 下载jquery.min.js 下载jquery.pagination.js 下载pagination.css 开始敲代码 第一步,引入刚刚下载的三个文件 <link r ...

  6. 在Scrapy中如何利用Xpath选择器从HTML中提取目标信息(两种方式)

    前一阵子我们介绍了如何启动Scrapy项目以及关于Scrapy爬虫的一些小技巧介绍,没来得及上车的小伙伴可以戳这些文章: 手把手教你如何新建scrapy爬虫框架的第一个项目(上) 手把手教你如何新建s ...

  7. NodeJS学习笔记 (3)域名解析-dns(ok)

    域名解析:dns.lookup() 比如我们要查询域名 www.qq.com 对应的ip,可以通过 dns.lookup() . var dns = require('dns'); dns.looku ...

  8. GDOI2018爆炸记

    Day0 12:45p.m. 从初中部出发前回班探望了一下同学,受到热烈欢迎(?) 13:15p.m. 出发去中山,路上本来想用mac看fz的,结果ass字幕导入失败,心态爆炸*1:后来成功获取xfz ...

  9. Spring Boot基础教程》 第1节工具的安装和使用

    <Spring Boot基础教程> 第1节 工具的安装和使用 Spring Boot文档 https://qbgbook.gitbooks.io/spring-boot-reference ...

  10. ActiveMQ服务安装

    1.下载安装ActiveMQ服务提供者 http://activemq.apache.org/ 2.启用ActiveMQ服务 cd [activemq_install_dir] bin\activem ...