最优贸易(tarjan,spfa)

时间:2021-09-28 02:48:16

题目描述

C国有n个大城市和m 条道路,每条道路连接这 n个城市中的某两个城市。任意两个城市之间最多只有一条道路直接相连。这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道路在统计条数时也计为 1条。

C国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。

商人阿龙来到 C国旅游。当他得知同一种商品在不同城市的价格可能会不同这一信息之后,便决定在旅游的同时,利用商品在不同城市中的差价赚回一点旅费。设 C国 n 个城市的标号从 1~ n,阿龙决定从 1号城市出发,并最终在 n 号城市结束自己的旅行。在旅游的过程中,任何城市可以重复经过多次,但不要求经过所有 n 个城市。阿龙通过这样的贸易方式赚取旅费:他会选择一个经过的城市买入他最喜欢的商品――水晶球,并在之后经过的另一个城市卖出这个水晶球,用赚取的差价当做旅费。由于阿龙主要是来 C 国旅游,他决定这个贸易只进行最多一次,当然,在赚不到差价的情况下他就无需进行贸易。

假设 C国有 5个大城市,城市的编号和道路连接情况如下图,单向箭头表示这条道路为单向通行,双向箭头表示这条道路为双向通行。

最优贸易(tarjan,spfa)

假设 1 n1~n1 n 号城市的水晶球价格分别为 4,3,5,6,1

阿龙可以选择如下一条线路:1->2->3->5,并在 2号城市以3 的价格买入水晶球,在 3号城市以5的价格卖出水晶球,赚取的旅费数为 2。

阿龙也可以选择如下一条线路1->4->5->4->5,并在第1次到达5号城市时以 1的价格买入水晶球,在第 2次到达4 号城市时以6的价格卖出水晶球,赚取的旅费数为5。

现在给出 n个城市的水晶球价格,m 条道路的信息(每条道路所连接的两个城市的编号以及该条道路的通行情况)。请你告诉阿龙,他最多能赚取多少旅费。

思路:

这道题很简单,就是让我们找一个最小买入点和一个最大卖出点

首先,我们要缩一下点(其实不缩也可以),建一张新图

然后,我们从1点开始,跑一遍用点权更新的spfa(可以求出每个点之前的最小买入值)

然后,我们建一张反图,从m开始跑一个用点权更新的spfa,求出一个点之后卖出的最大值

对于每个新点,如果差价大于答案,就更新答案即可

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define rij register int j
#define rii register int i
using namespace std;
int low[],dfn[],top,sta[],bnt;
int n,m,head[],last[],dq[];
int sum[],color[],tot,vis[];
int maxn[],minx[],dp[],cnt;
int maxx[],mixx[],pd[];
struct cb{
int from,to,p;
}y[];
struct ljb{
int to,nxt,from;
}x[];
queue<int> q;
void add(int from,int to)
{
bnt++;
x[bnt].to=to;
x[bnt].from=from;
if(head[from]==)
{
head[from]=bnt;
}
else
{
x[last[from]].nxt=bnt;
}
last[from]=bnt;
}
void tarjan(int wz)
{
top++;
sta[top]=wz;
vis[wz]=;
cnt++;
dfn[wz]=cnt;
low[wz]=cnt;
for(rii=head[wz];i!=;i=x[i].nxt)
{
int ltt=x[i].to;
if(dfn[ltt]==)
{
tarjan(ltt);
low[wz]=min(low[wz],low[ltt]);
}
else
{
if(vis[ltt]==)
{
low[wz]=min(low[wz],dfn[ltt]);
}
}
}
if(dfn[wz]==low[wz])
{
tot++;
while(sta[top+]!=wz)
{
color[sta[top]]=tot;
vis[sta[top]]=;
maxn[tot]=max(maxn[tot],dq[sta[top]]);
minx[tot]=min(minx[tot],dq[sta[top]]);
top--;
}
}
}
void spfa(int wz)
{
pd[wz]=;
mixx[wz]=minx[wz];
for(rii=head[wz];i!=;i=x[i].nxt)
{
q.push(i);
}
while(q.empty()==false)
{
int ltt=q.front();
q.pop();
int to=x[ltt].to;
int from=x[ltt].from;
pd[from]=;
mixx[to]=min(mixx[to],minx[to]);
if(mixx[to]>mixx[from])
{
mixx[to]=mixx[from];
for(rii=head[to];i!=;i=x[i].nxt)
{
q.push(i);
}
}
if(pd[to]==)
{
for(rii=head[to];i!=;i=x[i].nxt)
{
q.push(i);
}
}
}
}
void spaf(int wz)
{
maxx[wz]=maxn[wz];
for(rii=head[wz];i!=;i=x[i].nxt)
{
q.push(i);
}
while(q.empty()==false)
{
int ltt=q.front();
q.pop();
int to=x[ltt].to;
int from=x[ltt].from;
pd[from]=;
maxx[to]=max(maxx[to],maxn[to]);
if(maxx[to]<maxx[from])
{
maxx[to]=maxx[from];
for(rii=head[to];i!=;i=x[i].nxt)
{
q.push(i);
}
}
if(pd[to]==)
{
for(rii=head[to];i!=;i=x[i].nxt)
{
q.push(i);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(rii=;i<=n;i++)
{
minx[i]=;
mixx[i]=;
}
for(rii=;i<=n;i++)
{
scanf("%d",&dq[i]);
}
for(rii=;i<=m;i++)
{
int from,to,p;
scanf("%d%d%d",&from,&to,&p);
y[i].from=from;
y[i].to=to;
y[i].p=p;
if(p==)
{
add(to,from);
}
add(from,to);
}
for(rii=;i<=n;i++)
{
if(dfn[i]==)
{
tarjan(i);
}
}
memset(head,,sizeof(head));
memset(last,,sizeof(last));
memset(x,,sizeof(x));
for(rii=;i<=m;i++)
{
int from=y[i].from;
int to=y[i].to;
int p=y[i].p;
if(color[from]!=color[to])
{
if(p==)
{
add(color[to],color[from]);
}
add(color[from],color[to]);
}
}
spfa(color[]);
memset(head,,sizeof(head));
memset(last,,sizeof(last));
memset(x,,sizeof(x));
memset(pd,,sizeof(pd));
for(rii=;i<=m;i++)
{
int from=y[i].from;
int to=y[i].to;
int p=y[i].p;
if(color[from]!=color[to])
{
if(p==)
{
add(color[from],color[to]);
}
add(color[to],color[from]);
}
}
spaf(color[n]);
int ans=;
while(q.empty()==false)
{
q.pop();
}
for(rii=;i<=n;i++)
{
ans=max(maxx[i]-mixx[i],ans);
}
cout<<ans;
}

最优贸易(tarjan,spfa)的更多相关文章

  1. &lbrack;NOIP2009&rsqb;&lbrack;LuoguP1073&rsqb; 最优贸易 - Tarjan,拓扑&plus;DP

    Description&Data 题面:https://www.luogu.org/problemnew/show/P1073 Solution Tarjan对联通块缩点,在DAG上按照拓扑序 ...

  2. luogu1073 最优贸易 &lpar;tarjan&plus;dp&rpar;

    tarjan缩点,然后按照拓扑序,做1号点能到达的点的答案具体做法是对每个点记一个min[i],max[i],vis[i]和ans[i]做拓扑序的时候,假设在从u点开始做,有边u到v,如果vis[u] ...

  3. 【题解】洛谷P1073 &lbrack;NOIP2009TG&rsqb; 最优贸易(SPFA&plus;分层图)

    次元传送门:洛谷P1073 思路 一开始看题目嗅出了强连通分量的气息 但是嫌长没打 听机房做过的dalao说可以用分层图 从来没用过 就参考题解了解一下 因为每个城市可以走好几次 所以说我们可以在图上 ...

  4. P1073 最优贸易 建立分层图 &plus; spfa

    P1073 最优贸易:https://www.luogu.org/problemnew/show/P1073 题意: 有n个城市,每个城市对A商品有不同的定价,问从1号城市走到n号城市可以最多赚多少差 ...

  5. 洛谷 P1073 最优贸易 最短路&plus;SPFA算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 P1073 最优贸易 题目描述 C国有 $ n $ 个大城市和 ...

  6. 洛谷 P1073 最优贸易 解题报告

    P1073 最优贸易 题目描述 \(C\)国有\(n\)个大城市和\(m\)条道路,每条道路连接这\(n\)个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这\(m\)条道路中有一部分 ...

  7. 洛谷P1073 最优贸易 &lbrack;图论,DP&rsqb;

    题目传送门 最优贸易 题目描述 C 国有n 个大城市和m 条道路,每条道路连接这n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这m 条道路中有一部分为单向通行的道路,一部分为双向 ...

  8. NOIP2009 最优贸易

    3. 最优贸易 (trade.pas/c/cpp) [问题描述] C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间 多只有一条道路直接相连.这 m 条道 ...

  9. Codevs 1173 最优贸易 2009年NOIP全国联赛提高组

    1173 最优贸易 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description [问题描述] C 国有n ...

  10. Luogu P1073 最优贸易

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双 ...

随机推荐

  1. hdu 2459 &lpar;后缀数组&plus;RMQ&rpar;

    题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...

  2. linux命令学习-2-dmesg

    DMESG NAME dmesg - print or control the kernel ring buffer(打印或者控制内核环缓冲) Usage: dmesg [options] Optio ...

  3. echo 在shell及脚本中显示色彩及闪烁警告效果

    在shell脚本编写中,echo用于输出字符串等提示信息,当我们需要格外显示色彩及闪烁效果如下: 一.在执行shell中显示色彩: 语法格式: echo -e "\033[颜色1:颜色2m ...

  4. C&num;批量向数据库插入数据

    程序中,批量插入数据有两种思路. 1.用for循环,一条一条的插入,经实测,这种方式太慢了(插入一万条数据至少都需要6-7秒),因为每次插入都要打开数据库连接,执行sql,关闭连接,显然这种方式不可行 ...

  5. C&num;常用单元测试框架比较:XUnit、NUnit和Visual Studio(MSTest)

    做过单元测试的同学大概都知道以上几种测试框架,但我一直很好奇它们到底有什么不同,然后搜到了一篇不错的文章清楚地解释了这几种框架的最大不同之处. 地址在这里:http://www.tuicool.com ...

  6. Vue&period;js学习笔记之修饰符详解

    本篇将简单介绍常用的修饰符. 在上一篇中,介绍了 v-model 和 v-on 简单用法.除了常规用法,这些指令也支持特殊方式绑定方法,以修饰符的方式实现.通常都是在指令后面用小数点“.”连接修饰符名 ...

  7. &lbrack;Luogu5161&rsqb;WD与数列&lpar;后缀数组&sol;后缀自动机&plus;线段树合并&rpar;

    https://blog.csdn.net/WAautomaton/article/details/85057257 解法一:后缀数组 显然将原数组差分后答案就是所有不相交不相邻重复子串个数+n*(n ...

  8. BZOJ 3261 最大异或和 可持久化Trie树

    题目大意:给定一个序列,提供下列操作: 1.在数组结尾插入一个数 2.给定l,r,x,求一个l<=p<=r,使x^a[p]^a[p+1]^...^a[n]最大 首先我们能够维护前缀和 然后 ...

  9. python解析HTML之&colon;PyQuery库的介绍与使用

    本篇大部分转载于https://www.jianshu.com/p/c07f7cd1b548 先放自已自己解析techweb一个网站图片的代码 from pyquery import PyQuery ...

  10. ICP 求解相机思路

    1.之前仍然是需要创建find_feature_matches,和pixel2cam,一个是用来匹配描述子的,一个是把像素坐标转成归一化平面坐标的.里面的变量都要带上&.2.因为是3d-3d. ...