假期计划
假期计划
由于要考虑相邻城市之间的中转点不超过 bfs
接下来是重点:对于每个点,都记录一个从
这个做法的确很好,但为什么取贡献前三名的点呢?
假如留一个,万一
假如留两个,如下图
上图中,无论
留三个,如下图
就算有
思路还是有点难想的,就当作刷新一下自己的认知。
代码需要注意,图可能不连通。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define Ls(i,l,r) for(int i=l;i<=r;++i)
#define Rs(i,l,r) for(int i=r;i>l;--i)
#define L(i,l) for(int i=0;i<l;++i)
typedef long long ll;
const int N=2510,M=20010,INF=0x3f3f3f3f;
int n,m,k,h[N],e[M],ne[M],idx,dis[N][N],q[N];
ll d[N],tu[3][N],res;
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void bfs(int s,int dis[]){
memset(dis,0x3f,N*4);
dis[s]=0;
int hh=0,tt=0;
q[tt++]=s;
while(hh<tt){
int u=q[hh++];
for(int i=h[u];~i;i=ne[i]){
int v=e[i];
if(dis[v]==INF){
dis[v]=dis[u]+1;
q[tt++]=v;
}
}
}
}
int main(){
memset(h,-1,sizeof h);
scanf("%d%d%d",&n,&m,&k);
++k;
Ls(i, 2, n)scanf("%lld",d+i);
while(m--){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
Ls(i, 1, n)bfs(i,dis[i]);
Ls(i, 2, n)
Ls(j, 2, n){
if(i!=j&&dis[1][i]<=k&&dis[i][j]<=k){
ll v=d[i];
if(v>=d[tu[0][j]])
tu[2][j]=tu[1][j],tu[1][j]=tu[0][j],tu[0][j]=i;
else if(v>=d[tu[1][j]])
tu[2][j]=tu[1][j],tu[1][j]=i;
else if(v>=d[tu[2][j]])tu[2][j]=i;
}
}
ll a[3],b[3];
Ls(i, 2, n)
Ls(j, 2, n){
if(i==j||dis[i][j]>k)continue;
int cnta=0,cntb=0;
L(k, 3)if(tu[k][i]&&tu[k][i]!=j)a[cnta++]=tu[k][i];
L(k, 3)if(tu[k][j]&&tu[k][j]!=i)b[cntb++]=tu[k][j];
L(k, cnta)
L(l, cntb)
if(a[k]!=b[l]){
ll tmp=d[a[k]]+d[i]+d[j]+d[b[l]];
if(tmp>res)res=tmp;
}
}
printf("%lld",res);
return 0;
}
本文作者:wscqwq
本文链接:https://www.cnblogs.com/wscqwq/p/17417885.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步