- 比较新颖的见图方式: a + b = c 边: (a) —b —> (c) | (b) —a—> (c)
- 另外使用spfa更新出边是 dis[j] = max(dis[t], dis[w[i]]) + max(time[t], tmie[w[i]]), 既保证更新产生j的时间 要在 t, w[i]两个更晚产生的一个后面进行杂交(边长也是花费为max(time[t], tim[w[i]])
#include "bits/stdc++.h"
using namespace std;
const int N = 100010;
int n, m, k, T;
int c[N];
bool hav[N]; // 是否拥有该种子
int h[N], e[N * 2], ne[N * 2], w[N * 2], idx;
bool st[N];
int dis[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
int spfa()
{
memset(dis, 0x3f, sizeof dis);
queue<int> q;
for(int i = 1; i <= n; i++)
if(hav[i])
{
dis[i] = 0;
q.push(i);
st[i] = true;
}
while(!q.empty())
{
int t = q.front();
q.pop();
st[t] = false;
for(int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if(dis[j] > max(dis[t], dis[w[i]]) + max(c[t], c[w[i]])) // max(dis[t], dis[w[i]]) 保证a, b都已经存在了,才可以杂交出c
{
dis[j] = max(dis[t], dis[w[i]]) + max(c[t], c[w[i]]);
if(!st[j])
{
q.push(j);
st[j] = true;
}
}
}
}
return dis[T];
}
int main()
{
cin >> n >> m >> k >> T;
for(int i = 1; i <= n; i++) cin >> c[i];
for(int i = 1; i <= m; i++)
{
int x;
cin >> x;
hav[x] = true;
}
memset(h, -1, sizeof h);
for(int i = 1; i <= k; i++)
{
int x, y, z;
cin >> x >> y >> z;
add(x, z, y); // x + y = z
add(y, z, x); // y + x = z
}
cout << spfa() << endl;
return 0;
}
这个建图太妙了