NOIP2013 D1 T3 货车运输
好吧,遇上这种题,作为蒟蒻的我第一个想到的就是怎么打暴力,然而暴力都打不好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。
输入输出样例
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。
--------------------------------------------------------分割线--------------------------------------------------------
仔细思考一下,其实求最大载重量就是求出货车从某点到另一点的所有路径中最小权值最大的一条,于是可以用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 货车运输的更多相关文章
- NOIP2013 DAY2 T3火车运输
传送门 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况 ...
- [NOIP2013][LGOJ P1967]货车运输
Problem Link 题目描述 A国有n座城市,编号从1到n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重 ...
- [NOIP2013提高组]货车运输
题目:洛谷P1967.Vijos P1843.codevs3287. 题目大意:有n个城市m条道路,每条道路有一个限重,规定货车运货不能超过限重.有一些询问,问你两个城市之间一次最多能运多少重的货(可 ...
- 【NOIP2013/Codevs3287】货车运输-最小生成树(大)-树上倍增
https://www.luogu.org/problemnew/show/P1967 由题可知,我们走的路的边应尽可能大,所以通过kruscal建最大生成树的图,再树上倍增,注意可能有多棵树; #i ...
- [NOIP2013 提高组] 货车运输
前言 使用算法:堆优化 \(prim\) , \(LCA\) . 题意 共有 \(n\) 个点,有 \(m\) 条边来连接这些点,每条边有权值.有 \(q\) 条类似于 \(u\) \(v\) 询问, ...
- NOIP2013 货车运输(最大生成树,倍增)
NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...
- [Luogu 1967] NOIP2013 货车运输
[Luogu 1967] NOIP2013 货车运输 一年多前令我十分头大的老题终于可以随手切掉了- 然而我这码风又变毒瘤了,我也很绝望. 看着一年前不带类不加空格不空行的清纯码风啊,时光也好像回去了 ...
- xsy 2018 【NOIP2013】货车运输
[NOIP2013]货车运输 Description A 国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有q辆货车在运输货物,司机们想知道每辆车在不超 ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
随机推荐
- AJAX 状态值与状态码详解
1- AJAX状态值与状态码区别 AJAX状态值是指,运行AJAX所经历过的几种状态,无论访问是否成功都将响应的步骤,可以理解成为AJAX运行步骤.如:正在发送,正在响应等,由AJAX对象与服务器交互 ...
- Packet Tracer 5.0 构建CCNA实验(3)—— 路由器实现vlan间通信
--交换机配置 --交换机和路由器连接的接口 switchport mode trunk --路由器配置 enable conf t int fa0/0.1 --路由器接口的子接口 encapsula ...
- js_beautifier && css_beautifier for emeditor
// // Unpacker for Dean Edward's p.a.c.k.e.r, a part of javascript beautifier // written by Einar Li ...
- 铺地砖|状压DP练习
有一个N*M(N<=5,M<=1000)的棋盘,现在有1*2及2*1的小木块无数个,要盖满整个棋盘,有多少种方式?答案只需要mod1,000,000,007即可. //我也不知道这道题的来 ...
- 【BZOJ】1492: [NOI2007]货币兑换Cash
[题意]初始资金s,有两种金券A和B,第i天,买入时将投入的资金购买比例为rate[i]的两种股票,卖出时将持有的一定比例的两种股票卖出,第i天股票价格为A[i],B[i],求最大获利.n<=1 ...
- JS的全局函数eval解析JSON字符串
JavaScript eval() 函数 定义和用法 eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码. 语法 eval(string) 参数 描述 string 必需. ...
- 超级ping(多线程版)
发现学校公共wifi的ip段是10.1.0-255.0-255段的,还是之前的思路批量ping一波. 其实可以使用nmap的.但是脚本写都写了.是吧.你懂的. #!/usr/bin/env pytho ...
- py,pyc,pyw文件的区别和使用
熟悉python编程的都知道,python三种最常见的py文件格式,.py,.pyc,.pyw,下面说一说它们各自的使用. py文件 python最常见的文件,是python项目的源码: 文件执行时l ...
- 当while read line 遇到 ssh
问题:while read line 中使用ssh只能读取一行? #!/bin/sh while read line do echo $line ssh root@$line "echo 1 ...
- vue数据传递--我有特殊的实现技巧
最近碰到了比较多的关于vue的eventBus的问题,之前定技术选型的时候也被问到了,vuex和eventBus的使用范围.所以简单的写一下.同时有一种特殊的实现方案. 有这么几种数据传递方式,vue ...