洛谷传送门

看到这个题,原本想先从后往前dfs,求出能到终点的点,再在这些点里从前往后spfa,用一条边上的两个城市的商品价格的差来作边权,实施过后,发现图中既有负边权,又有回路,以及各种奇奇怪怪的东西。说实话我连样例都没过,然后提交一下试试,得了10分。

然而我发现,要求赚最多钱,就是到那个点的路径上的最大价格 - 最小价格。

两边dfs——

最小价格可以从前往后搜来算。

最大价格可以从后往前搜来算。

最后枚举一边所有点maxx - minn的最大值就好。

说出来你可能不信,我是看的题解。

——代码

#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream> using namespace std; int n, m, cnt1, cnt2, ans;
int a[], next1[], to1[], head1[], next2[], to2[],
head2[], maxx[], minn[]; inline void add1(int x, int y)
{
to1[cnt1] = y;
next1[cnt1] = head1[x];
head1[x] = cnt1++;
} inline void add2(int x, int y)
{
to2[cnt2] = y;
next2[cnt2] = head2[x];
head2[x] = cnt2++;
} inline void dfs2(int u, int k)
{
int i, v;
maxx[u] = max(maxx[u], k);
for(i = head2[u]; i != -; i = next2[i])
{
v = to2[i];
if(maxx[v] < k) dfs2(v, max(k, a[v]));
}
} inline void dfs1(int u, int k)
{
int i, v;
minn[u] = min(minn[u], k);
for(i = head1[u]; i != -; i = next1[i])
{
v = to1[i];
if(minn[v] > k) dfs1(v, min(k, a[v]));
}
} int main()
{
int i, j, x, y, z;
memset(head1, -, sizeof(head1));
memset(head2, -, sizeof(head2));
scanf("%d %d", &n, &m);
for(i = ; i <= n; i++)
{
scanf("%d", &a[i]);
maxx[i] = -1e9;
minn[i] = 1e9;
}
for(i = ; i <= m; i++)
{
scanf("%d %d %d", &x, &y, &z);
if(z == )
{
add1(x, y);
add1(y, x);
add2(x, y);
add2(y, x);
}
else
{
add1(x, y);
add2(y, x);
}
}
dfs1(, a[]);
dfs2(n, a[n]);
for(i = ; i <= n; i++) ans = max(ans, maxx[i] - minn[i]);
printf("%d", ans);
return ;
}

其中dfs不用设置vis来记录是否被访问过,因为有双向道路,所以走到一个点有可能会返回来,所以进行深搜的判断标准是目标点(姑且这么说吧)的最大最小值小于或大于当前点的最大最小值。这样即使走到后面的点,发现前面的点需要修改,也可以改回去。

也可以用 spfa ,改变一下松弛操作,dis 数组表示到当前点的路径上买入的最小值,最后统计一遍就行。

——代码

 #include <queue>
#include <cstdio>
#include <cstring>
#include <iostream> using namespace std; const int MAXN = ;
int n, m, cnt, cnt1, ans;
int a[MAXN], head[MAXN], to[MAXN], next[MAXN], head1[MAXN], to1[MAXN], next1[MAXN], dis[MAXN];
bool b[MAXN], vis[MAXN];
queue <int> q; inline void add(int x, int y)
{
to[cnt] = y;
next[cnt] = head[x];
head[x] = cnt++;
} inline void add1(int x, int y)
{
to1[cnt1] = y;
next1[cnt1] = head1[x];
head1[x] = cnt1++;
} inline void dfs(int u)
{
int i, v;
b[u] = ;
for(i = head1[u]; i != -; i = next1[i])
{
v = to1[i];
if(!b[v]) dfs(v);
}
} inline void spfa(int u)
{
int i, v;
memset(dis, / , sizeof(dis));
q.push(u);
dis[u] = a[u];
while(!q.empty())
{
u = q.front();
q.pop();
vis[u] = ;
for(i = head[u]; i != -; i = next[i])
{
v = to[i];
if(dis[v] > min(dis[u], a[v]) && b[v])
{
dis[v] = min(dis[u], a[v]);
if(!vis[v])
{
q.push(v);
vis[v] = ;
}
}
}
}
} int main()
{
int i, j, x, y, z;
scanf("%d %d", &n, &m);
for(i = ; i <= n; i++) scanf("%d", &a[i]);
memset(head, -, sizeof(head));
memset(head1, -, sizeof(head1));
for(i = ; i <= m; i++)
{
scanf("%d %d %d", &x, &y, &z);
if(z == )
{
add(x, y);
add1(y, x);
}
else
{
add(x, y);
add(y, x);
add1(x, y);
add1(y, x);
}
}
dfs(n);
spfa();
for(i = ; i <= n; i++)
if(b[i])
ans = max(ans, a[i] - dis[i]);
printf("%d", ans);
return ;
}

NOIP2009T3最优贸易(Dfs + spfa)的更多相关文章

  1. NOIP2009T3最优贸易

    洛谷传送门 看到这个题,原本想先从后往前dfs,求出能到终点的点,再在这些点里从前往后spfa,用一条边上的两个城市的商品价格的差来作边权,实施过后,发现图中既有负边权,又有回路,以及各种奇奇怪怪的东 ...

  2. 【题解】洛谷P1073 [NOIP2009TG] 最优贸易(SPFA+分层图)

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

  3. P1073 最优贸易 建立分层图 + spfa

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

  4. 洛谷 P1073 最优贸易 最短路+SPFA算法

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

  5. NOIP2009 最优贸易

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

  6. 洛谷P1073 最优贸易 [图论,DP]

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

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

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

  8. Luogu P1073 最优贸易

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

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

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

随机推荐

  1. MySQL执行带out的存储过程

    CALL `sp_sys_get_code`(3,'sys_customer',@code); SELECT @code

  2. 从 fn_dbLog 解析操作日志(补充update)

    过去经常听到SQL server 日志,可是在提供的界面上看到的Log不是我们想要的,我们想窥探具体的数据操作日志.专业恢复追踪数据库操作日志的软件:ApexSQLLog,偶然发现SQL Server ...

  3. iOS 二维码扫描 通过ZBar ZXing等第三方库

    扫描二维码的开源库有很多如 ZBar.ZXing等 ZBar的使用方法: 下载ZBar SDK 地址https://github.com/bmorton/ZBarSDK ZBarSDK是一个开源的SD ...

  4. How the performance impacts your revenue-性能影响营收

    看完国外一个APM厂商最后的一个业务介绍视频,终于想通了PE领域中最顶层的应用目标,也就是如标题所云.那么这个影响效果是如何做到的?最终的步骤其实很简单,也就是利用大数据进行分析.而自己先前还没有想到 ...

  5. C/C++ static

    C/C++中static关键字作用总结 1.先来介绍它的第一条也是最重要的一条:隐藏.(static函数,static变量均可) 当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全 ...

  6. whereis参数

    -b  只找二进制文件 -m 只找在帮助文件manual路径下的文件 -s 只找原文件 -u 没有帮助文件的文件 whereis passwd

  7. CATransaction 知识

    CATransaction 事务类,可以对多个layer的属性同时进行修改.它分隐式事务,和显式事务. 区分隐式动画和隐式事务:隐式动画通过隐式事务实现动画 . 区分显式动画和显式事务:显式动画有多种 ...

  8. DROP AGGREGATE - 删除一个用户定义的聚集函数

    SYNOPSIS DROP AGGREGATE name ( type ) [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP AGGREGATE 将删除一个现存聚集 ...

  9. JAVA用freemarker生成复杂Excel。(freemarker)

    在生成Excel的时候,大多时候都是使用poi,jxl等进行的,但是对于复杂的Excel来说,这个工作量是非常的大的,而且,对于我这么懒的人来说,这是相当痛苦的一件事情,所以,我不得不找找有没有简单一 ...

  10. 牛客noip前集训营(第一场)提高T1

    链接:https://www.nowcoder.com/acm/contest/172/A来源:牛客网 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个 ...