题目链接

先\(Tarjan\)缩点,记录每个环内的最大值和最小值。

然后跑拓扑排序,\(Min[u]\)表示到\(u\)的最小值,\(ans[u]\)表示到\(u\)的答案,\(Min\)和\(ans\)都在拓扑排序中更新和传递。

最终答案就是\(ans[n]\)。

\(100\)多行敲着心累

#include <cstdio>
#include <cstring>
#define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout);
#define Close fclose(stdin);fclose(stdout);
namespace IO{
int xjc; char ch;
inline int read(){
xjc = 0; ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){ xjc = xjc * 10 + ch - '0'; ch = getchar(); }
return xjc;
}
}using namespace IO;
inline int max(int a, int b){
return a > b ? a : b;
}
inline int min(int a, int b){
return a > b ? b : a;
}
const int MAXN = 100010;
const int MAXM = 500010;
struct Queue{
int s[MAXN];
int head, tail;
inline void push(int x){
s[++tail] = x;
}
inline int pop(){
return s[++head];
}
inline int size(){
return tail - head;
}
}q;
struct Edge{
int from, next, to;
};
struct Graph{
int head[MAXN], num;
Edge e[MAXM << 1];
inline void Add(int from, int to){
e[++num].to = to; e[num].from = from; e[num].next = head[from]; head[from] = num;
}
}G, T, P;
int dfn[MAXN], low[MAXN], id, vis[MAXN], stack[MAXN], w[MAXN], top, cnt, belong[MAXN], v[MAXN];
int minw[MAXN], maxw[MAXN], now, in[MAXN], Min[MAXN], ans[MAXN];
void Tarjan(int u){
dfn[u] = low[u] = ++id; vis[u] = 1; stack[++top] = u;
for(int i = G.head[u]; i; i = G.e[i].next)
if(!dfn[G.e[i].to]){
Tarjan(G.e[i].to);
low[u] = min(low[u], low[G.e[i].to]);
}
else if(vis[G.e[i].to])
low[u] = min(low[u], dfn[G.e[i].to]);
if(dfn[u] == low[u]){
++cnt;
do{
now = stack[top--];
vis[now] = 0;
belong[now] = cnt;
minw[cnt] = min(minw[cnt], w[now]);
maxw[cnt] = max(maxw[cnt], w[now]);
P.Add(cnt, now);
}while(now != u);
}
}
int n, m, a, b, c;
int main(){
Open("trade");
memset(minw, 127, sizeof minw);
memset(Min, 127, sizeof Min);
n = read(); m = read();
for(int i = 1; i <= n; ++i)
w[i] = read();
for(int i = 1; i <= m; ++i){
a = read(); b = read(); c = read();
G.Add(a, b);
if(c == 2) G.Add(b, a);
}
for(int i = 1; i <= n; ++i)
if(!dfn[i])
Tarjan(i);
for(int i = 1; i <= cnt; ++i){
for(int j = P.head[i]; j; j = P.e[j].next){
int u = P.e[j].to;
for(int k = G.head[u]; k; k = G.e[k].next)
if(belong[G.e[k].to] != i && !v[belong[G.e[k].to]]){
v[belong[G.e[k].to]] = 1;
T.Add(i, belong[G.e[k].to]);
++in[belong[G.e[k].to]];
}
}
for(int j = P.head[i]; j; j = P.e[j].next){
int u = P.e[j].to;
for(int k = G.head[u]; k; k = G.e[k].next)
v[belong[G.e[k].to]] = 0;
}
}
q.push(belong[1]);
while(q.size()){
now = q.pop();
Min[now] = min(Min[now], minw[now]);
ans[now] = max(ans[now], maxw[now] - Min[now]);
for(int i = T.head[now]; i; i = T.e[i].next){
int v = T.e[i].to;
if(!(--in[v])) q.push(v);
Min[v] = min(Min[v], Min[now]);
ans[v] = max(ans[v], ans[now]);
}
}
printf("%d\n", ans[belong[n]]);
return 0;
}

【洛谷 P1073】 最优贸易 (Tarjan缩点+拓扑排序)的更多相关文章

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

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

  2. 洛谷P1073 最优贸易==codevs1173 最优贸易

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

  3. 洛谷——P1073 最优贸易

    P1073 最优贸易 n 个城市间以 m 条有向道路连接, 小 T 从 1 号城市出发, 将要去往 n 号城市.小 T 观察到一款商品 Z 在不同的城市的价格可能不尽相同,小 T 想要在旅行中的某一个 ...

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

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

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

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

  6. 洛谷 P1073 最优贸易

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

  7. 洛谷 P1073 最优贸易 & [NOIP2009提高组](反向最短路)

    传送门 解题思路 很长的题,实际上在一个有向图(点有点权)中求一个从起点1到终点n的路径,使得这条路径上点权最大的点与点权最小的点的差值最大(要求必须从点权较小的点能够走到点权较大的点). ——最短路 ...

  8. NOIP2009 codevs1173 洛谷P1073 最优贸易

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

  9. [NOIP2009] 提高组 洛谷P1073 最优贸易

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

  10. 洛谷P1073最优贸易——双向取值

    题目:https://www.luogu.org/problemnew/show/P1073 由于任何城市都可以多次经过,所以可以随便走,也就不用太在意有向边和无向边,把无向边当做两条有向边处理: 根 ...

随机推荐

  1. iOS-系统 图片、视频 管理控制器UIImagePickerController

        UIImagePickerController 是一个管理系统多媒体文件库(相册)中的图片.视频文件的视图控制器,诞生于iOS4之前,虽然功能不是很完善,我们仍可以用这个视图控制器做一些有创造 ...

  2. BZOJ 1082 栅栏(二分+DFS剪枝)

    首先,长度短的木板一定比长度长的木板容易得到,因此若要得到最多的木板,它们必定是所有木板中最短的——可以对木板排序后二分答案(用k表示). 判断是否合法就用搜索,但数据有点大,要用到两个剪枝.一个是若 ...

  3. IBatis Map时间参数文字格式不匹配!

    CS. ht.Add("start_time", startTime); Map <isNotNull prepend="and" property=&q ...

  4. [JSOI2010]部落划分 最小生成树

    一道最小生成树经典题 由于是最靠近的两个部落尽可能远,如果我们先处理出任意两个居住点之间的距离并将其当做边,那么我们可以发现,因为在一个部落里面的边是不用计入答案的,所以应该要尽量把小边放在一个部落里 ...

  5. 重拾C#教程:变量

    一个变量只不过是一个供程序操作的存储区的名字.在 C# 中,每个变量都有一个特定的类型,类型决定了变量的内存大小和布局.范围内的值可以存储在内存中,可以对变量进行一系列操作. 我们已经讨论了各种数据类 ...

  6. POJ1422:Air Raid——题解

    http://poj.org/problem?id=1422 题目大意:n个点m条有向边,每条边只能走一次,往点上放人让他们走遍所有边,问至少要多少人. —————————————————————— ...

  7. 洛谷4245:【模板】任意模数NTT——题解

    https://www.luogu.org/problemnew/show/P4245 给两个多项式,求其乘积,每个系数对p取模. 参考: 代码与部分理解参考https://www.luogu.org ...

  8. POJ3694:Network(并查集+缩点+lca)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 13172   Accepted: 4774 题目链接:htt ...

  9. 目标世界上最小的Linux系统—ttylinux体验

    ttylinux的官方网址:http://ttylinux.net/ 简单翻译一下: 你当前访问的是ttylinux的主页,一个针对多种CPU架构的极小的GNU/Linux系统.最小的ttylinux ...

  10. dubbo在项目中的应用

    关于dubbo的使用,我们举个简单例子: 存在2个系统,A系统和B系统,A系统调用B系统的接口获取数据,用于查询用户列表. 在上一篇博文介绍了dubbo的创建,zookeeper的创建完成后,我们可以 ...