题目描述

mzry1992 在打完吊针出院之后,买了辆新摩托车,开始了在周边城市的黄金运送生意。在mzry1992 生活的地方,城市之间是用双向高速公路连接的。另外,每条高速公路有一个载重上限,即在不考虑驾驶员和摩托车重量的情况下,如果所载货物的量超过某个值,则不能驶上该条高速公路。今年,mzry1992 一共收到了来自n 个不同城市的n 份定订单,每个订单要求卖出上限为一定量的黄金,或是要求买入上限为一定量的黄金。由于订单并不是同时发来的,为了维护生意上的名声,mzry1992 不得不按照订单发来的顺序与客户进行交易。他与第i 个客户进行交易的具体步骤是:
1. 前往第i 个客户所在城市。当然,中途是完全允许经过其他城市的。
2. 与第i 个客户进行交易,在此过程中他希望有限制的让交易额尽量大。具体的限制有两个
(a) 他希望与最后一个客户完成交易后,手上没有剩余黄金。
(b) 由于黄金是很贵重的物品,不能出现因为买入过多黄金而造成在以后的运送过程中不得不丢弃黄金的情况。
一开始,mzry1992 位于第一个订单客户所在的城市。现在有一个好消息,有人提供了mzry1992 免费试用周边城市的列车系统的资格。具体来讲,如果mzry1992希望从A 城市到达B 城市,且A、B 城市均有列车站的话,他可以携带着黄金与摩托车从A 城市乘坐列车到B 城市,这里假定乘坐列车没有载重限制。现在已知城市间的交通系统情况和订单情况,请帮助mzry1992 计算每个向mzry1992 购买黄金的客户的购买量。

输入

输入的第一行有三个整数n, m, q,分别表示城市数,连通城市的高速公路数和有列车站的城市数。

接下来的一行有n 个数,每个数均不相同,且值介于1 到n 之间,代表订单的顺序。

第三行有n 个数,第i 个数表示i 号城市的订单的上限额bi,bi 为正值表示该订单为买入交易(针对mzry1992 而言),上限为bi,bi 为负值表示该订单为卖出交易(同样针对mzry1992 而言)上限为 -bi。

接下来的m 行每行有三个数,u, v, w,表示城市u 和城市v 之间有一条载重上限为w 的高速公路,这里假定所有高速公路都是双向的,城市的序号是从1 到n 的。

输入的最后一行有q 个数,代表有列车站城市的序号。

对于20% 数据,n <= 100,m <= 200

对于50% 数据,n <= 3000,m <= 6000

对于100% 数据,1 <= n <= 10^5,n - 1 <= m <= 2*[1]10^5,0 <= q <= n,0 < |bi| < 10^9,0 < w < 10^9,保证任意两个城市之间是通过高速公路连通的。

输出

按照订单顺序对于每个卖出交易,输出一行,该行只有一个整数x,表示卖出黄金的量。

样例输入

Sample #1
3 3 2
2 3 1
-6 5 -3
1 3 5
2 3 2
2 1 6
1 3
Sample #2
4 4 0
1 2 3 4
5 4 -6 -1
1 2 4
2 3 100
3 4 1
4 1 4

样例输出

Sample #1
3
2
Sample #2
6
1
Hint
第一组样例:其中一种合法的方案是最初从2 号城市买入5 单位的黄金,先走第三条高速公路到1 号城市,然后再坐列车到3 号城市,在3 号城市卖出3 单位的黄金,然后乘坐列车到1 城市,在1 号城市卖出2 单位的黄金。
第二组样例:其中一种合法的方案是最初从1 号城市买入4 单位的黄金,走第一条高速公路,在2 号城市买入3 单位的黄金,走第二条高速公路,在三城市点卖出6 单位的黄金,走第三条高速公路,在4 号城市卖出1 单位的黄金。
 
 
从一个城市走到另一个城市一定是走限重大的道路,又因为有火车站这种东西,我们将有火车站的点之间依次连边,边权为INF,再找原图最大生成树。
最优方案一定是走最大生成树上的边。
每次买卖的限重就是最大生成树上路径上的最小边,像倍增LCA一样倍增求一下即可。
虽然题目中说不允许丢弃黄金,但我们可以贪心地到一个买黄金的点就将黄金全买下来,即使到后面黄金超过限重将多余的扔掉也可以相当于在之前不买扔掉的这些。
剩下的就是到每个点能买多少就买多少,能卖多少就卖多少模拟一下即可。

#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n,m,k,x;
ll INF=1e16;
int vis[100010];
int f[100010][20];
ll g[100010][20];
int d[100010];
int head[100010];
int to[200010];
int next[200010];
ll val[200010];
int fa[100010];
int cnt;
struct miku
{
int x;
int y;
ll v;
}a[500010];
ll v[100010];
int q[100010];
int tot;
ll now;
int find(int x)
{
if(fa[x]==x)
{
return x;
}
return fa[x]=find(fa[x]);
}
void add(int x,int y,ll z)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
val[tot]=z;
}
bool cmp(miku a,miku b)
{
return a.v>b.v;
}
void dfs(int x,int fa)
{
d[x]=d[f[x][0]]+1;
for(int i=1;i<=18;i++)
{
f[x][i]=f[f[x][i-1]][i-1];
g[x][i]=min(g[x][i-1],g[f[x][i-1]][i-1]);
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=fa)
{
f[to[i]][0]=x;
g[to[i]][0]=val[i];
dfs(to[i],x);
}
}
}
ll lca(int x,int y)
{
ll res=INF+100;
if(d[x]<d[y])
{
swap(x,y);
}
int dep=d[x]-d[y];
for(int i=0;i<=18;i++)
{
if((dep&(1<<i)))
{
res=min(res,g[x][i]);
x=f[x][i];
}
}
if(x==y)
{
return res;
}
for(int i=18;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
res=min(res,g[x][i]);
res=min(res,g[y][i]);
x=f[x][i];
y=f[y][i];
}
}
return min(res,min(g[x][0],g[y][0]));
}
int main()
{
memset(g,0x7f7f7f7f,sizeof(g));
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&q[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&v[i]);
fa[i]=i;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%lld",&a[i].x,&a[i].y,&a[i].v);
}
cnt=m;
for(int i=1;i<=k;i++)
{
scanf("%d",&vis[i]);
}
for(int i=2;i<=k;i++)
{
cnt++;
a[cnt].x=vis[1];
a[cnt].y=vis[i];
a[cnt].v=INF;
}
sort(a+1,a+1+cnt,cmp);
for(int i=1;i<=cnt;i++)
{
int fx=find(a[i].x);
int fy=find(a[i].y);
if(fx!=fy)
{
fa[fx]=fy;
add(a[i].x,a[i].y,a[i].v);
add(a[i].y,a[i].x,a[i].v);
}
}
dfs(q[1],0);
if(v[q[1]]>0)
{
now=v[q[1]];
}
else
{
printf("0\n");
}
for(int i=1;i<n;i++)
{
ll lim=lca(q[i],q[i+1]);
now=min(now,lim);
if(v[q[i+1]]>0)
{
now+=1ll*v[q[i+1]];
}
else
{
printf("%lld\n",min(now,-v[q[i+1]]));
now=max(0ll,now+v[q[i+1]]);
}
}
}

BZOJ3322[Scoi2013]摩托车交易——最大生成树+贪心+倍增的更多相关文章

  1. 2019.03.28 bzoj3322: [Scoi2013]摩托车交易(kruskal重构树+贪心)

    传送门 题意咕咕咕 思路: 先把所有可以列车通的缩成一个点,然后用新图建立kruskalkruskalkruskal重构树. 这样就可以倒着贪心模拟了. 代码: #include<bits/st ...

  2. BZOJ3322 : [Scoi2013]摩托车交易

    求出最大生成树,则两点间的最大容量为树上两点间的边权的最小值. 设$lim[i]$表示第$i$个订单的城市允许携带的黄金上限,则 $lim[i]=\min(lim[i+1],a[i]和a[i+1]点间 ...

  3. [SCOI2013]摩托车交易 kruskal重构树(最大生成树) 倍增

    ---题面--- 题解: 这题想法简单,,,写起来真的是失智,找了几个小时的错误结果是inf没开到LL范围.... 首先我们需要找到任意两点之间能够携带黄金的上限值,因为是在经过的道路权值中取min, ...

  4. 【SCOI2013】摩托车交易 - 最大生成树+树链剖分

    题目描述 mzry1992 在打完吊针出院之后,买了辆新摩托车,开始了在周边城市的黄金运送生意.在mzry1992 生活的地方,城市之间是用双向高速公路连接的.另外,每条高速公路有一个载重上限,即在不 ...

  5. 【[SCOI2013]摩托车交易 】

    倍增什么的最慢了,常数太大了 我们可以上树剖啊 但是如果用树剖来查询树上两点之间的最小边权的话,可能只能在上一棵线段树? 那也太\(naive\)了,尽管倍增常数大,但是还是比两个\(log\)快的 ...

  6. [SCOI2013]摩托车交易 题解

    思路分析 为了让交易额尽量大,显然我们需要尽量多地买入.对于每个城市,到达这个城市时携带的黄金受到几个条件的影响:之前卖出的黄金,之前能买入的最多的黄金,前一个城市到当前城市的路径上的最小边权.既然不 ...

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

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

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

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

  9. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

随机推荐

  1. ASP.NET 加密解密

    1.MD5 2.DES 一 MD5 介绍:MD5是不可逆解密方式,比如对密码的加密,为了保密,让密码不能解密 public static string MD5Encrypt(string str) { ...

  2. Git使用—第一讲:初识版本控制工具

    几乎所有出色的项目都不是一个人完成的,而是由一个团队共同合作开发完成的,这个时候多人之间的代码同步问题就显得异常重要了,因此版本控制工具也就应运而生了.常见的版本控制工具主要有SVN和Git,接下来要 ...

  3. Linux下ftp安装配置及三种用户的验证

    一.原理简介 二.安装配置 三.三种用户的验证 一.简介 FTP即文件传输协议(File Transfer Protocol),完成各主机的文件共享功能,基于客户端-服务器的协议,工作在应用层,tcp ...

  4. ESP8266使用详解(AT,LUA,SDK)

    https://www.cnblogs.com/yangfengwu/p/10100152.html             8266综合开发教程(LUA) https://www.cnblogs.c ...

  5. odoo中的ORM操作

    ORM方法简介 OpenERP的关键组件, ORM是一个完整的对象关系映射层,是开发人员不必编写基本的SQL管道. 业务对象被声明继承字models.Models的python类. 这让业务对象在OR ...

  6. NOIp2018停课刷题记录

    Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...

  7. 【LGR-049】洛谷7月月赛

    Preface Luogu八月月赛都结束了我才来补七月月赛 这次月赛还是很狗的,在绍一的晚上恰逢刮台风,然后直接打到一半断网了 结果都没有交上去GG 感觉这次难度适中,解法也比较清新自然吧,十分给个九 ...

  8. 通用漏洞评估方法CVSS3.0简表

    CVSS3.0计算分值共有三种维度: 1. 基础度量. 分为 可利用性 及 影响度 两个子项,是漏洞评估的静态分值. 2. 时间度量. 基础维度之上结合受时间影响的三个动态分值,进而评估该漏洞的动态分 ...

  9. 将 C# 枚举序列化为 JSON 字符串 基础理论

    该转换过程需要引用 Newtonsoft.JSON,这其中的转换过程还是蛮有意思的. 一.定义枚举 /// <summary> /// 托寄物品枚举 /// </summary> ...

  10. wordcount程序中的应用与拓展

    设计思路: 关键是思路,首先知道 单词, 行,字符, 他们有什么特点: 1.单词,标准的是遇到空格后,单词数,自动加一. 2.行是以\n结束的, 也就是说, 遇到\n行数加一,当然也视你的操作系统而言 ...