求助
查看原帖
求助
310439
星星与辰楼主2022/10/30 10:05
#include<bits/stdc++.h>
using namespace std;
inline int read() {
	int num = 0;
	char ch = getchar();
	while(!isdigit(ch)) ch = getchar();
	while(isdigit(ch)) num = (num << 1) + (num << 3) + (ch & 15) , ch = getchar();
	return num ;
}
long long val[2510] ;
int q[2510] , nxt[20010] , to[20010] , head[2510] , ma1[2510] , ma2[2510] , ma3[2510] , dis[2510][2510];
int n , k , cnt , a[4];
bool vis[2510];
inline void add(const int x,const int y) {
	nxt[++cnt] = head[x] , head[x] = cnt , to[cnt] = y;
	nxt[++cnt] = head[y] , head[y] = cnt , to[cnt] = x;
}

inline void bfs(const int st) {
	int head1 = 1 , tail = 1;
	q[1] = st;
	dis[st][st] = 1;
	while(head1 <= tail) {
		const int x = q[head1++];
		if(dis[st][x] == k + 2) {
			continue;
		}
		for (int i = head[x] ; i ; i = nxt[i]) {
			if(dis[st][to[i]]) continue;
			dis[st][to[i]] = dis[st][x] + 1;
			q[++tail] = to[i];
		}
	}
}


void dfs(const int x , const int cs) {
	if(cs == 2) {
		//插入能到该点的最大、次大、次次大的点
		if(val[a[1]] > val[ma1[a[2]]]) {
			ma3[a[2]] = ma2[a[2]];
			ma2[a[2]] = ma1[a[2]];
			ma1[a[2]] = a[1];
		}else if(val[a[1]] > val[ma2[a[2]]]) {
			ma3[a[2]] = ma2[a[2]];
			ma2[a[2]] = a[1];
		}else if(val[a[1]] > val[ma3[a[2]]]) {
			ma3[a[2]] = a[1];
		}
		return;
	}
	
	//可以到达但没选
	for (int i = 2 ; i <= n ; ++ i) {
		if(dis[x][i] && !vis[i]) {
			a[cs + 1] = i;
			vis[i] = true;
			dfs(i , cs + 1);
			vis[i] = false;
		}
	}
}

inline bool cmp (const int x , const int y) {
	if(val[x] == val[y]) {
		return x < y;
	}
	return val[x] > val[y];
}
inline long long Max(const long long x , const long long y) {
	return x < y ? y : x;
}
int main() {
	n = read() ;
	int m = read() ;
	k = read();
	for (int i = 2 ; i <= n ; ++ i ) {
		val[i] = read();
	}
	
	while(m--) {
		int x = read() , y = read();
		add(x , y);
	}
	
	//跑一遍每一个点能到达什么
	for (int i = 1 ; i <= n ; ++ i) {
		for (int j = 1 ; j <= n ; ++ j) {
			vis[j] = false;
		}
		bfs(i);
	}
	
	for (int i = 2 ; i <= n ; ++ i) vis[i] = false;
	dfs(1,0);
	
	long long ans = 0;
	
	for (int i = 2 ; i <= n ; ++ i) {
		if(ma1[i])for (int j = i + 1 ; j <= n ; ++ j) {
			//钦定i、j为中间的确定的B、C点
			if(dis[i][j] && ma1[j]) {
				//确定i能选什么点
				if(ma1[i] != j) {
					//在这样的基础上再确定j能选什么点
					if(ma1[j] != i && ma1[i] != ma1[j]) {
						ans = Max(ans , val[i] + val[j] + val[ma1[i]] + val[ma1[j]]);
					}else if(ma2[j] != i && ma2[j] && ma1[i] != ma2[j]) {
						ans = Max(ans , val[i] + val[j] + val[ma1[i]] + val[ma2[j]]);
					}else ans = Max(ans , val[i] + val[j] + val[ma1[i]] + val[ma3[j]]);
				}
				if(ma2[i] != j && ma2[i]) {
					if(ma1[j] != i && ma2[i] != ma1[j]) {
						ans = Max(ans , val[i] + val[j] + val[ma2[i]] + val[ma1[j]]);
					}else if(ma2[j] != i && ma2[j] && ma2[i] != ma2[j]) {
						ans = Max(ans , val[i] + val[j] + val[ma2[i]] + val[ma2[j]]);
					}else ans = Max(ans , val[i] + val[j] + val[ma2[i]] + val[ma3[j]]);
				}
				if(ma3[i] != j && ma3[i]) {
					if(ma1[j] != i && ma3[i] != ma1[j]) {
						ans = Max(ans , val[i] + val[j] + val[ma3[i]] + val[ma1[j]]);
					}else if(ma2[j] != i && ma2[j] && ma2[i] != ma2[j]) {
						ans = Max(ans , val[i] + val[j] + val[ma3[i]] + val[ma2[j]]);
					}else ans = Max(ans , val[i] + val[j] + val[ma3[i]] + val[ma3[j]]);
				}
			}
		}
	}
	
	printf("%lld",ans);
	return 0;
}
2022/10/30 10:05
加载中...