85pts,TLE,求大佬帮忙优化
查看原帖
85pts,TLE,求大佬帮忙优化
1004850
blue_dreamQAQ楼主2023/7/6 15:07

借鉴的第一篇题解的思路

#include<bits/stdc++.h>

using namespace std;

int n,m,k;
long long ans;
long long w[2505];
int g[2505][2505],mp[2505][2505];
//g[i][j]=f[j][i]=1表示点i,j之间有直达线路,其实就是存一下图 
//mp[i][j]=1表示通过BFS确定k次转车后i能到j点,=0则不能 
int f[2505][3];//f[u][k]表示u可达,且在家附近的,权值第k大的景点
//f[i][0]是最优,f[i][1]是次优,f[i][2]是次次优 

void bfs(int x){//通过BFS确定从x点能到哪些点(u),能到的mp[x][u]=1 
	int dis[2505]={0};
	queue<int> q;
	q.push(x);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		if(u!=x){
			mp[x][u]=1;
		}
		if(dis[u]==k+1) continue;
		for(int i=1;i<=n;i++){
			if(g[u][i] && dis[i]==0 && i!=x){
				q.push(i);
				dis[i]=dis[u]+1;
			}
		}
	}
}

bool cmp(int a,int b){
	return w[a]>w[b];
}

int main(){
	//板块1:输入存图 
	scanf("%d%d%d",&n,&m,&k);
	for(int i=2;i<=n;i++){
		scanf("%lld",&w[i]);
	}
	for(int i=1,x,y;i<=m;i++){
		scanf("%d%d",&x,&y);
		g[x][y]=mp[x][y]=g[y][x]=mp[y][x]=1;
	}
	//板块二:处理图,判断i(不)借助转车能到哪些点 
	for(int i=1;i<=n;i++){
		bfs(i);
	}
	//板块三:循环得b,c可达,且在家附近的,权值最大/次大/次次大的点 
	for(int i=2;i<=n;i++){
		int s=0;
		for(int j=2;j<=n;j++){
			if(mp[i][j] && mp[j][1]){
				if(s!=3){
					f[i][s++]=j;
					sort(f[i],f[i]+3,cmp);
				}else{
					if(w[j]>w[f[i][2]]){
						f[i][2]=j;
						sort(f[i],f[i]+3,cmp);
					}
				}
			}
		}
	}
	//板块四:循环b,c所有情况,列举f[b][i],f[c][j]所有情况,求最优解 
	for(int b=2;b<=n;b++){
		for(int c=2;c<=n;c++){	
			if(mp[b][c]){
				for(int i=0;i<3;i++){
					for(int j=0;j<3;j++){
						if(f[b][i]!=0 && f[c][j]!=0){
							int a=f[b][i],d=f[c][j];
							if(a!=d && a!=c && b!=d){
								ans=max(ans,w[a]+w[b]+w[c]+w[d]);
							}
						}
					}
				}
			}
		}
	}

	printf("%lld",ans);
	
	return 0;
}
2023/7/6 15:07
加载中...