认为写的是O(n2)正解,可能常数大了点,但是为什么会WA几个点?
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=4010;
int n,m,k,val[maxn];
int too[maxn][maxn];//是否合法
int to2[maxn];
int dis[maxn];//距离
vector<int> dp[maxn];//dp[i]:存储离i,1都很近的前三大
int head[maxn],nxt[maxn],to[maxn],tot;
inline void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
inline void bfs(int x)
{
memset(dis,-1,sizeof(dis));
dis[x]=0;
queue<int> q;
q.push(x);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(dis[v]==-1)
{
dis[v]=dis[u]+1;
q.push(v);
}
}
}
}
signed main()
{
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=2;i<=n;i++)scanf("%lld",&val[i]);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%lld%lld",&x,&y);
add(x,y);add(y,x);
}
for(int i=1;i<=n;i++)
{
bfs(i);
if(i==1)
{
for(int j=1;j<=n;j++)to2[j]=dis[j];
}
for(int j=2;j<=n;j++)
{
if(i==j)continue;
if(dis[j]<=k+1)too[i][j]=1;
if(dis[j]<=k+1 && to2[j]<=k+1)
{
dp[i].push_back(j);
}
}
sort(dp[i].begin(),dp[i].end(),[](int u, int v)
{
return val[u]>val[v];
});
while(dp[i].size()>=4)dp[i].pop_back();
}
int ans=0;
for(int b=2;b<=n;b++)
{
for(int c=2;c<=n;c++)
{
if(!too[b][c])continue;
for(int a:dp[b])
{
for(int d:dp[c])
{
if(a!=c && a!=d && b!=d)
{
ans=max(ans,val[a]+val[b]+val[c]+val[d]);
}
}
}
}
}
printf("%lld\n",ans);
return 0;
}