不完全AC。
错 Substack #1 的 11、17 号测试点
//#pragma GCC optimize (2)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e3 + 5e2 + 5;
const int M = 2e4 + 5;
const int INF = -1e16;
int read () {
int x = 0, y = 1;
char c = getchar ();
while (c < '0' || c > '9') {
if (c == '-') y = -1;
c = getchar ();
}
while (c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + c - '0';
c = getchar ();
}
return x * y;
}
void write (int x) {
if (x < 0) putchar ('-'), x = -x;
if (x > 9) write (x / 10);
putchar (x % 10 + '0');
}
int n, m, k, cnt, ans;
int head[N];
struct node { // 链式前向星
int v, w;
int nxt;
};
node a[M];
int s[N]; // 点权
int f[4][N], dis[N][N]; // f[k][i] 表示从1出发到i号经过一个点的编号u(点权为所有可能u的第k大)
bool vis[N][N];
void add (int u, int v, int w) {
a[ ++ cnt].nxt = head[u];
a[cnt].v = v;
a[cnt].w = w;
head[u] = cnt;
}
void bfs (int s) { // dis 表示最短路
queue <int> q;
q.push (s);
dis[s][s] = 0;
while (!q.empty ()) {
int u = q.front ();
q.pop ();
for (int i = head[u]; i; i = a[i].nxt) {
int v = a[i].v;
if (!vis[s][v]) {
dis[s][v] = dis[s][u] + 1;
vis[s][v] = true;
q.push (v);
}
}
}
}
void init (int u) { // 寻找 f[k][i]
for (int i = 2; i <= n; i ++ ) {
if (i == u) continue;
if (dis[1][i] <= k + 1 && dis[1][i] != 0 && dis[u][i] <= k + 1 && dis[u][i] != 0) {
if (s[i] > s[f[1][u]]) {
f[3][u] = f[2][u];
f[2][u] = f[1][u];
f[1][u] = i;
} else if (s[i] > s[f[2][u]]) {
f[3][u] = f[2][u];
f[2][u] = i;
} else if (s[i] > s[f[3][u]]) {
f[3][u] = i;
}
}
}
}
void fun (int u, int v) { // 枚举所有 B、C,寻找答案
if (f[1][u] == 0 || f[1][v] == 0) return ;
int j;
for (int i = 1; i <= 3; i ++ ) {
if (f[i][u] == v) continue;
j = 1;
while (f[j][v] == f[i][u] || f[j][v] == u) j ++ ; // A不能与C、D相同
ans = max (ans, s[f[i][u]] + s[u] + s[v] + s[f[j][v]]);
}
}
signed main () {
n = read (), m = read (), k = read ();
for (int i = 1; i < n; i ++ ) s[i + 1] = read ();
for (int i = 1; i <= m; i ++ ) {
int u = read (), v = read (), w = 1;
add (u, v, w), add (v, u, w);
}
s[0] = INF;
for (int i = 1; i <= n; i ++ ) bfs (i);
for (int i = 2; i <= n; i ++ ) init (i);
for (int i = 2; i <= n; i ++ ) {
for (int j = 2; j <= n; j ++ ) {
if (i == j) continue;
if (dis[i][j] <= k + 1 && dis[i][j] != 0) fun (i, j);
}
}
write (ans);
putchar ('\n');
return 0;
}