【35.00%】【z13】&&【b093】最优贸易
【题解】
这题就是要在n个点里面选一个花费最小的点。然后找一个花费最大的点。两者之差为最大值。
但是最大值的点要在最小值的点之后出现。且走到后者之后要能够到达N号节点。为了处理掉环。先用tarjan进行缩点。这样整张图就不会出现环了。接下来进行DP即可。记录到达某个点之前所能买到的最低价格。然后尝试在这个点卖掉。记录最优值。然后把最优值一直往后传。最后输出f[n]。这里的DP用了记忆化搜索。或者说是一个强力剪枝。自己看吧。
【代码】
//#pragma comment(linker,"/STACK:102400000,102400000")
#include <cstdio>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;
const int MAXN = 100000 + 100;
struct data2
{
int sell, min;
};
int n, m, dx = 0, nn = 0, bh[MAXN];
int price[MAXN], dfn[MAXN], low[MAXN], ma_x[MAXN], mi_n[MAXN], ans = 0;
data2 f[MAXN];
vector <int> a[MAXN], aa[MAXN];
stack <int> z;
int zzz[MAXN];
bool flag[MAXN] = { 0 };
bool used[MAXN] = { 0 };
void tarjan(int x)
{
flag[x] = true;
dfn[x] = low[x] = ++dx;
zzz[x] = z.size();
z.push(x);
int len = a[x].size();
for (int i = 0; i <= len - 1; i++)
{
int y = a[x][i];
if (!flag[y])
{
tarjan(y);
low[x] = min(low[x], low[y]);
}
else
if (zzz[y] >0)
low[x] = min(low[x], dfn[y]);
}
if (low[x] == dfn[x])
{
nn++;
int tma = price[x], tmi = price[x], limit = zzz[x];
while (z.size() != limit)
{
int t = z.top();
tma = max(tma, price[t]);
tmi = min(tmi, price[t]);
bh[t] = nn;
zzz[t] = 0;
z.pop();
}
ma_x[nn] = tma;
mi_n[nn] = tmi;
}
}
void dfs(int now, int pre)
{
bool can = false; //这个can表示这个点有没有更新。如果没有更新任何东西就剪枝
if (f[now].min > f[pre].min)
{
f[now].min = f[pre].min;
can = true;
}
if (f[now].min > mi_n[now])
{
f[now].min = mi_n[now];
can = true;
}
if (f[now].sell < ma_x[now] - f[pre].min)
{
f[now].sell = ma_x[now] - f[pre].min;
can = true;
}
if (f[now].sell < ma_x[now] - mi_n[now])
{
f[now].sell = ma_x[now] - mi_n[now];
can = true;
}
if (f[now].sell < f[pre].sell)//答案往后传
{
f[now].sell = f[pre].sell;
can = true;
}
if (!can)
return;
int len = aa[now].size();
for (int i = 0; i <= len - 1; i++)
if (!used[aa[now][i]])
{
used[aa[now][i]] = true;
dfs(aa[now][i], now);
used[aa[now][i]] = false;
}
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &price[i]);
for (int i = 1; i <= m; i++)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
a[x].push_back(y);
if (z == 2) a[y].push_back(x);
}
tarjan(1);
for (int i = 1; i <= n; i++)
if (bh[i] != 0)//bh数组记录了缩点后i号点新的编号
{
int len = a[i].size();
for (int j = 0; j <= len - 1; j++)
{
int y = a[i][j];
if (bh[y] != 0 && bh[i] != bh[y])
aa[bh[i]].push_back(bh[y]);
}
}
for (int i = 1; i <= nn; i++)
f[i].min = 2100000000;
int qidian = bh[1];//从起点开始dfs+dp
used[qidian] = true;
f[qidian].min = mi_n[qidian];//一开始就可能在环里面
f[qidian].sell = ma_x[qidian] - mi_n[qidian];
int len = aa[qidian].size();
for (int i = 0; i <= len - 1; i++)
if (!used[aa[qidian][i]])
{
used[aa[qidian][i]] = true;
dfs(aa[qidian][i], qidian);
used[aa[qidian][i]] = false;
}
printf("%d\n", f[bh[n]].sell);
return 0;
}
【35.00%】【z13】&&【b093】最优贸易的更多相关文章
- 「NOIP2009」最优贸易
「NOIP2009」最优贸易 「NOIP2009」最优贸易内存限制:128 MiB时间限制:1000 ms 题目描述C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意 ...
- 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], ...
- 洛谷P1073 最优贸易==codevs1173 最优贸易
P1073 最优贸易 题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一 ...
随机推荐
- 逐步配置企业版Symantec Norton防病毒服务器
逐步配置企业版Symantec Norton防病毒服务器 配置企业版Symantec Norton NT操作系统,已经安装IIS 安装Symantec Norton 10 安装系统中心 650) th ...
- Node.js安装+环境配置【Windows版】
Node.js安装及环境配置之Windows篇 一.安装环境 1.本机系统:Windows 10 Pro(64位)2.Node.js:v6.9.2LTS(64位) 二.安装Node.js步骤 1.下 ...
- SpringCloud核心教程 | 第一篇: 使用Intellij中的Spring Initializr来快速构建Spring Cloud工程
spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运行环 ...
- 【Tomcat】严重: Context [/grouponAdminWeb] startup failed due to previous errors
1 tomcat 6600启动报错[root@localhost webapps]# sh /usr/local/apache-tomcat-6.0.37_6600/bin/startup.s ...
- OpenShift 自定义 OPENSHIFT_DOCUMENT_ROOT 变量,替换网站根目录路径!
OpenShift 自定义 OPENSHIFT_DOCUMENT_ROOT 变量,替换网站根目录路径! 预先定义的子目录 :) DIY: DocumentRoot=${OPENSHIFT_RE ...
- 16、cgminer学习之:pthread_mutex_init和pthread_cond_init
1.原理 假设有两个线程同时访问一个全局变量 n,这个全局变量的初始值等于0. Int n = 0 ; 消费者线程 A 进入临界区,访问 n,A 必须等到 n 大于 0 才能接着往下执行,如果 n= ...
- Costura.Fody
使用Costura.Fody将源DLL合并到目标EXE 本文为原创文章,如转载,请在网页明显位置标明原文名称.作者及网址,谢谢! 一.本文主要是使用Costura.Fody工具将源DLL合并到目标EX ...
- Loadrunner--负载生成器
对场景进行设计后,接着需要对负载生成器进行管理和设置.Load Generator是运行脚本的负载引擎,在默认情况下使用本地的负载生成器来运行脚本,但是模拟用户行为也需要消耗一定的系统资源,所以在一台 ...
- jmeter--基本组件介绍
一.JMeter 介绍 Apache JMeter是100%纯Java桌面应用程序,被设计为用于测试客户端/服务端结构的软件(例如web应用程序).它可以用来测试静态和动态资源的性能,例如:静态文件, ...
- 洛谷——P1022 计算器的改良
https://www.luogu.org/problem/show?pid=1022#sub 题目背景 NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在 ...