做法是记录两步到达某个点的最大值,次大值和次次大值。
但是在合并两个点的时候强制其中一个点必须取最大值。
请问能否 hack?/kel
Code:
#include<bits/stdc++.h>
using namespace std;
// #define int long long
#define i64 long long
#define u64 unsigned long long
#define pii pair<u64,int>
inline i64 read(void) {
i64 x=0,sgn=0; char c=getchar();
while(c <'0'||c> '9') { sgn=(c=='-'); c=getchar();}
while('0'<=c&&c<='9') { x=x*10+c-48; c=getchar(); }
return sgn ? -x :x ;
}
void write(u64 x) {
if(x<10) putchar(x+48);
else write(x/10),putchar(x%10+48);
}
int n,m,k;
vector <int> E[2503];
// vector <int> E2[2503];
bool T[2503][2503];
int que[2503],ql,qr,qd[2503];
int vis[2503];
u64 score[2503];
inline void bfs(int rot) {
ql=qr=0;
que[++qr]=rot; qd[qr]=0; vis[rot]=1;
while(ql<qr) {
int x=que[++ql],d=qd[ql];
if(d==k) continue;
for(int v : E[x]) {
if(vis[v]) continue;
que[++qr]=v;
qd[qr]=d+1;
vis[v]=1;
T[rot][v]=1;
// E2[v].push_back(x);
}
}
}
inline bool distinct(int a,int b,int c,int d) {
if(a==b||a==c||a==d||b==c||b==d||c==d) return 0;
return 1;
}
pii stk[2503]; int stop=0;
int f[2503][3];
u64 s[2503][3];
u64 Ans;
signed main() {
n=read(); m=read(); k=read()+1;
for(int i=2; i<=n; ++i) score[i]=read();
for(int i=1,x,y; i<=m; ++i) {
x=read(); y=read();
E[x].push_back(y);
E[y].push_back(x);
}
for(int i=1; i<=n; ++i) {
for(int u=1; u<=n; ++u) vis[u]=0;
bfs(i);
}
for(int v=1; v<=n; ++v) if(T[1][v]) stk[++stop]=make_pair(score[v],v);
sort(stk+1,stk+stop+1);
for(int i=2; i<=n; ++i) {
int cnt=0;
for(int u=stop; u>=1; --u) {
if(T[i][stk[u].second]) {
f[i][cnt]=stk[u].second;
s[i][cnt]=score[stk[u].second]+score[i];
++cnt;
if(cnt==3) break;
}
}
}
for(int i=2; i<=n; ++i) if(f[i][0]) {
for(int u=2; u<=n; ++u) if(T[i][u]&&u!=f[i][0]) {
if(distinct(i,f[i][0],u,f[u][0])&&f[u][0]) {
Ans=max(Ans,s[i][0]+s[u][0]);
} else if(distinct(i,f[i][0],u,f[u][1])&&f[u][1]) {
Ans=max(Ans,s[i][0]+s[u][1]);
} else if(distinct(i,f[i][0],u,f[u][2])&&f[u][2]){
Ans=max(Ans,s[i][0]+s[u][2]);
}
}
}
write(Ans); puts("");
return 0;
}