好吧,遇上这种题,作为蒟蒻的我第一个想到的就是怎么打暴力,然而暴力都打不好QAQ!!!于是只能等教练讲解以后,然后在大犇的指导下终于做出来了。

对了,,好像还,没上题。。。。:

题目描述

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

说明

对于 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。

--------------------------------------------------------分割线--------------------------------------------------------

仔细思考一下,其实求最大载重量就是求出货车从某点到另一点的所有路径中最小权值最大的一条,于是可以用kruskal算法先处理出最大生成树,然后在树上进行倍增求lca,同时求出lca过程中经过的最小权值就行了。问题就在于如何在lca过程中求最小权值;很显然,直接在倍增过程中暴力求是行不通的,所以要预处理,在进行倍增预处理的同时记录下跳跃的该段中的最小权值,然后就可以很轻(ma)松(fan)的过了。如果还是有点不懂,请参考下列代码,其中有解释:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int inf=0x7f7f7f7f;
const int maxn=(int)1e5+;
int n,m,tot,g[maxn],head[maxn],fa[maxn][],mm[maxn][];
//mm数组记录每次跳跃过程中跳跃段中的最小权值
int f[maxn],dep[maxn],minn=0x7fffffff;
bool vis[maxn];
struct Tree{
int to,val,next;
}road[maxn];
struct Edge{
int f,t,v;
}e[maxn];//邻接链表,不解释
inline int read()//读优,这个应该打得比较清楚
{
char ch=getchar();int num=;bool flag=false;
if(ch<''||ch>'')
if(ch=='-') flag=true,ch=getchar();
else ch=getchar();
while(ch>=''&&ch<='')
{num=num*+ch-'';
ch=getchar();}
return flag?-num:num;
}
void clear(int pd)//对数组进行预先处理
{
tot=;
if(pd)
{
memset(e,,sizeof(e));
memset(mm,0x7f,sizeof(mm));
}
memset(head,-,sizeof(head));
for(int i=;i<=n;i++)
f[i]=i;
}
bool cmp(Edge a,Edge b)
{return a.v>b.v;}
int find(int x)
{
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
}
void add(int u,int v,int w)
{
road[++tot].to=v;
road[tot].val=w;
road[tot].next=head[u];
head[u]=tot;
}
void build()//kruskal算法,如果不会,出门左转自行百度
{
int a,b;
sort(e+,e+m+,cmp);
for(int i=;i<=m;i++)
{
a=find(e[i].f);
b=find(e[i].t);
if(a!=b)
{
add(e[i].f,e[i].t,e[i].v);
add(e[i].t,e[i].f,e[i].v);
f[a]=b;
}
if(tot==m*-)break;
}
}
void dfs(int x)
//深搜进行预处理,当然,预处理还有另外一种用两个变量的写法,我就不写了,可以到网上去看看
//据说那种写法比这种要好一点,
{
for(int i=;i<=;i++)
{
if(mm[x][i-]<inf)
mm[x][i]=min(mm[x][i-],mm[fa[x][i-]][i-]);
    /*这个应该不难理解,每次跳的时候都要更新最小值,切记,要在向上跳之前记录*/
fa[x][i]=fa[fa[x][i-]][i-];
}
vis[x]=;
for(int i=head[x];i!=-;i=road[i].next)
{
int y=road[i].to;
if(y!=fa[x][])
{
dep[y]=dep[x]+;
mm[y][]=road[i].val;
      /*这里解释下,某一点跳一步的最小权值就是这两点间的权值*/
fa[y][]=x;
dfs(y);
}
}
}
int lca(int u,int v)//倍增求lca,不解释
{
if(dep[u]<dep[v]) swap(u,v);
int d=dep[u]-dep[v];
for(int i=;i<=;i++)
if(d&(<<i))
{
minn=min(minn,mm[u][i]);
u=fa[u][i];
}
if(u==v) return minn;
for(int i=;i>=;i--)
{
if(fa[u][i]!=fa[v][i])
{
minn=min(minn,min(mm[u][i],mm[v][i]));
u=fa[u][i];
v=fa[v][i];
}
}
minn=min(minn,min(mm[u][],mm[v][]));
return minn;
}
int main()
{
int x,y,q;
scanf("%d%d",&n,&m);
clear();
for(int i=;i<=m;i++)
{
e[i].f=read();
e[i].t=read();
e[i].v=read();
}
scanf("%d",&q);
build();//最大生成树
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++)
if(!vis[i]) dfs(i);//进行lca倍增预处理
for(int i=;i<=q;i++)
{
scanf("%d%d",&x,&y);
minn=inf;
if(find(x)!=find(y))
{printf("-1\n");continue;}
printf("%d\n",lca(x,y));
}
return ;
}

-----------------------------------------------------------------分割线-----------------------------------------------------------------------

作为第三题,果然还是有点难度的,神犇的路还很漫长,加油吧!

NOIP2013 D1 T3 货车运输的更多相关文章

  1. NOIP2013 DAY2 T3火车运输

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

  2. [NOIP2013][LGOJ P1967]货车运输

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

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

    题目:洛谷P1967.Vijos P1843.codevs3287. 题目大意:有n个城市m条道路,每条道路有一个限重,规定货车运货不能超过限重.有一些询问,问你两个城市之间一次最多能运多少重的货(可 ...

  4. 【NOIP2013/Codevs3287】货车运输-最小生成树(大)-树上倍增

    https://www.luogu.org/problemnew/show/P1967 由题可知,我们走的路的边应尽可能大,所以通过kruscal建最大生成树的图,再树上倍增,注意可能有多棵树; #i ...

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

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

  6. NOIP2013 货车运输(最大生成树,倍增)

    NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...

  7. [Luogu 1967] NOIP2013 货车运输

    [Luogu 1967] NOIP2013 货车运输 一年多前令我十分头大的老题终于可以随手切掉了- 然而我这码风又变毒瘤了,我也很绝望. 看着一年前不带类不加空格不空行的清纯码风啊,时光也好像回去了 ...

  8. xsy 2018 【NOIP2013】货车运输

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

  9. NOIP2013 货车运输 (最大生成树+树上倍增LCA)

    死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...

随机推荐

  1. centos7-java模拟cpu占用高及排查

    环境 centos7 1核2GB Java8 模拟cpu占用高 新建一个名为jvm-learn的springboot项目 模拟代码如下 import org.springframework.boot. ...

  2. CentOS下安装JDK1.8

    0.卸载旧版本 键入命令java-version,查询当前JDK版本 如果版本号不是想要的,键入rpm -qa|grep gcj 键入命令 yum -y remove (后接查询得到的版本),移除老版 ...

  3. Python学习笔记(三十三)常用内置模块(2)collections_namedtuple_deque_defaultdict_OrderedDict_Counter

    摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431953239 ...

  4. c++ poco 使用mysql中文乱码问题

    poco 是c++ 一个比较好的库,现在正在学习使用它,碰到一些问题记录在此. poco版本:poco-1.46-all ,带有数据库的支持模块 操作系统:ubuntu 1.使用poco的MySQL模 ...

  5. 关于HttpWebRequest发生服务器协议冲突的解决办法

    WinForm下的app.config文件中添加: <system.net>    <settings>      <httpWebRequest useUnsafeHe ...

  6. css3全屏背景显示

    background:url(zhongyi2.png) no-repeat center center fixed;/* -webkit-background-size:cover; -moz-ba ...

  7. 24、简述Python的深浅拷贝以及应用场景

    深浅拷贝的原理 深浅拷贝用法来自copy模块. 导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝 ...

  8. 关于select联动的两种做法

    第一种方法: function dong(){      var getSheng = document.getElementById("sheng");      var get ...

  9. Python 类的名称空间和组合

    一.Python类的名称空间 class Student(object): School = '北京大学' def __init__(self): pass stu1 = Student() stu1 ...

  10. scrapy shell 用法(慢慢更新...)

    scrapy shell 命令 1.scrapy shell url #url指你所需要爬的网址 2.有些网址数据的爬取需要user-agent,scrapy shell中可以直接添加头文件, 第①种 ...