NOIP2009T3最优贸易
看到这个题,原本想先从后往前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最优贸易的更多相关文章
- NOIP2009T3最优贸易(Dfs + spfa)
洛谷传送门 看到这个题,原本想先从后往前dfs,求出能到终点的点,再在这些点里从前往后spfa,用一条边上的两个城市的商品价格的差来作边权,实施过后,发现图中既有负边权,又有回路,以及各种奇奇怪怪的东 ...
- NOIP2009 最优贸易
3. 最优贸易 (trade.pas/c/cpp) [问题描述] C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间 多只有一条道路直接相连.这 m 条道 ...
- Codevs 1173 最优贸易 2009年NOIP全国联赛提高组
1173 最优贸易 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description [问题描述] C 国有n ...
- Luogu P1073 最优贸易
题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双 ...
- 洛谷 P1073 最优贸易 解题报告
P1073 最优贸易 题目描述 \(C\)国有\(n\)个大城市和\(m\)条道路,每条道路连接这\(n\)个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这\(m\)条道路中有一部分 ...
- CH6101 最优贸易【最短路】
6101 最优贸易 0x60「图论」例题 描述 C国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通 ...
- [Luogu 1073] NOIP2009 最优贸易
[Luogu 1073] NOIP2009 最优贸易 分层图,跑最长路. 真不是我恋旧,是我写的 Dijkstra 求不出正确的最长路,我才铤而走险写 SPFA 的- #include <alg ...
- 洛谷P1073 最优贸易 [图论,DP]
题目传送门 最优贸易 题目描述 C 国有n 个大城市和m 条道路,每条道路连接这n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这m 条道路中有一部分为单向通行的道路,一部分为双向 ...
- 【洛谷P1073】[NOIP2009]最优贸易
最优贸易 题目链接 看题解后感觉分层图好像非常NB巧妙 建三层n个点的图,每层图对应的边相连,权值为0 即从一个城市到另一个城市,不进行交易的收益为0 第一层的点连向第二层对应的点的边权为-w[i], ...
随机推荐
- QQ微信刷屏助手 FlashScreenAssist 1.2发布
主要功能 文字刷屏 图片刷屏 简易教程 文字刷屏 打开软件之后输入要刷屏的文字,点击[开始],然后点一下微信或者QQ的输入框,就会开始刷屏了,注意[时间间隔]不要调太小,越小越快. 要注意的是.必须在 ...
- 使用GDI绘制文本
/// <summary> /// 定义一个绘制文本 /// </summary> public void Texts() ...
- iOS 原生的 UIButton 点击事件是不允许带多参数的,唯一的一个参数就是默认UIButton本身 那么我们该怎么实现传递多个参数的点击事件呢?
UIButton *btn = // create the button objc_setAssociatedObject(btn, "firstObject", someObje ...
- Servlet+Tomcat日志输出
刚接触Servlet的时候,为了学习方便总是想验证自己的想法,那么输出日志是最常见的手法了,就自己亲身经历总结了如下几种方法,我用的是Web容器是Tomcat. 使用Log4J 在<Servle ...
- css3滚动效果
.css{ -webkit-transition-duration: .3s; transition-duration: .3s; }
- Java基础——第一个记事本代码与Java注释
一 .使用记事本编辑java文件: 1.打开记事本,重命名文件名,文件拓展名“.java”.(必须要的,系统才能识别java文件) 2.编写一个简单的java代码: public class Hell ...
- String.format()的总结
JAVA字符串格式化-String.format()的使用 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的spri ...
- shiro学习笔记_0100_shiro简介
前言:第一次知道shiro是2016年夏天,做项目时候我要写springmvc的拦截器,申哥看到后,说这个不安全,就给我捣鼓了shiro,我就看了下,从此认识了shiro.此笔记是根据网上的视频教程记 ...
- 在WPF应用程序中使用Font Awesome图标
Font Awesome 在网站开发中,经常用到.今天介绍如何在WPF应用程序中使用Font Awesome . 如果是自定义的图标字体,使用方法相同. 下载图标字体 在官方网站或github上下载资 ...
- WP8.1小梦词典开发1:金山词霸API使用
原文出自:http://www.bcmeng.com/windows-phone-api/ 今天开始小梦给大家分享一下小梦词典开发中几个关键问题,首先我们来看查词功能的实现.小梦词典的查词功能是通过金 ...