You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 100010, M = 2000010;
int n, m;
int dis1[N], dis2[N];
// 正反建图,传入头数组指针
int h1[N], h2[N], e[M], ne[M], w[M], idx;
void add(int *h, int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
// 每个节点的价值
int v[N];
void dijkstra1() {
memset(dis1, 0x3f, sizeof dis1);
priority_queue<PII, vector<PII>, greater<PII>> q;
dis1[1] = v[1];
q.push({dis1[1], 1});
while (q.size()) {
int u = q.top().second;
q.pop();
for (int i = h1[u]; ~i; i = ne[i]) {
int j = e[i];
if (dis1[j] > min(dis1[u], v[j])) {
dis1[j] = min(dis1[u], v[j]);
q.push({dis1[j], j});
}
}
}
}
void dijkstra2() {
memset(dis2, -0x3f, sizeof dis2);
priority_queue<PII> q;
dis2[n] = v[n];
q.push({dis2[n], n});
while (q.size()) {
int u = q.top().second;
q.pop();
for (int i = h2[u]; ~i; i = ne[i]) {
int j = e[i];
if (dis2[j] < max(dis2[u], v[j])) {
dis2[j] = max(dis2[u], v[j]);
q.push({dis2[j], j});
}
}
}
}
int main() {
// 正反两张图
// Q:为什么要反着建图,用正着的图不行吗?
// A:不行啊因为从n向其它地方走原来的有向图无法向对面走啊反着建图就行了
memset(h1, -1, sizeof h1);
memset(h2, -1, sizeof h2);
scanf("%d %d", &n, &m); // n个节点m条边
for (int i = 1; i <= n; i++) scanf("%d", &v[i]); // 每个节点购买水晶球的金额
while (m--) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
// 不管是单向边还是双向边第一条a->b的边肯定跑不了吧
if (c == 1) { // 单向边
// 正向图保存单向边
add(h1, a, b);
// 反向图保存单向边
add(h2, b, a);
// 注意:这可不是在一个图中创建两条来回的边,而是在两个图中创建两个相反的边。
// 权值呢没有为什么呢因为我们不关心边权而是关心此节点中水晶球的价格v[i],这并不是边权,可以理解为点权
} else { // 双向边
// 正向图保存双向边
add(h1, a, b), add(h1, b, a);
// 反向图保存双向边
add(h2, a, b), add(h2, b, a);
}
}
// 正向图跑一遍dijkstra
dijkstra1();
// 反向图跑一遍dijkstra
dijkstra2();
int ans = 0;
for (int i = 1; i <= n; i++)
ans = max(dis2[i] - dis1[i], ans);
printf("%d\n", ans);
return 0;
}