比赛 CSP2022提高组 评测结果 AAAAAAAAAAAAAAAAAATT
题目名称 假期计划 最终得分 90
用户昵称 ZRQ 运行时间 5.819 s
代码语言 C++ 内存使用 3.41 MiB
提交时间 2022-10-30 12:23:02
显示代码纯文本
#include<bits/stdc++.h>
#define ll long long
#define iter set<int>::iterator
using namespace std;
const int N=5005,M=20005;
struct node
{
	ll w;
	int id;
	bool operator < (const node &x) const {return x.w>w;}
};
int n,m,k,dep[N];
int hd[N],nt[M<<1],e[M<<1],idx,id[N][5];
char ch;
set<int> s[N],ss[N],t;
ll x,ans,w[N];
inline ll read(){x=0;ch=getchar();while(ch<48||ch>57)ch=getchar();while(ch>47&&ch<58)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x;}
inline void add(int x,int y){nt[++idx]=hd[x],hd[x]=idx,e[idx]=y;}
void BFS1(int st)//1ci
{
	memset(dep,0,sizeof(dep));
	queue<int> q;
	q.push(st);
	dep[st]=1;
	while(!q.empty())
	{
		int cur=q.front();
		q.pop();
		for(int i=hd[cur];i;i=nt[i])
			if(!dep[e[i]]||dep[e[i]]>dep[cur]+1)
			{
				dep[e[i]]=dep[cur]+1;
				if(dep[e[i]]<k+2) q.push(e[i]);
			}
	}
	for(int i=1;i<=n;++i)
		if(dep[i]&&i!=st)
			s[st].insert(i),s[i].insert(st);
	return ;
}
int main()
{
	freopen("csp2022_holiday.in","r",stdin);
	freopen("csp2022_holiday.out","w",stdout);
	n=read(),m=read(),k=read();
	for(int i=2;i<=n;++i) w[i]=read();
	for(int i=1,x,y;i<=m;++i) x=read(),y=read(),add(x,y),add(y,x);
	for(int i=1;i<=n;++i)
		BFS1(i);
	for(iter it=s[1].begin();it!=s[1].end();++it)
		t.insert(s[*it].begin(),s[*it].end());
	for(int i=2;i<=n;++i)
	{
		priority_queue<node> q;
		for(iter it=s[i].begin();it!=s[i].end();++it)
		{
			if(*it==i||s[1].find(*it)==s[1].end()) continue;
			q.push((node){w[*it],*it});
		}
		for(int j=0;j<3;++j)
		{
			if(q.empty()) break;
			id[i][j]=q.top().id;
			q.pop();
		}
	}
	for(iter i=t.begin();i!=t.end();++i)
	{
		if(*i==1||s[*i].size()==1) continue;
		iter j=i;
		++j;
		for(;j!=t.end();++j)
		{
			if(s[*i].find(*j)==s[*i].end()||s[*j].size()==1) continue;
			ll res=w[*i]+w[*j];
			int si=0,sj=0;
			if(id[*i][si]==*j) ++si;
			if(id[*j][sj]==*i) ++sj;
			if(id[*i][si]==0||id[*j][sj]==0) continue;
			if(id[*i][si]==id[*j][sj])
			{
				res+=w[id[*i][si]];
				ll k=0;
				++si,++sj;
				if(id[*i][si]==*j) ++si;
				if(id[*j][sj]==*i) ++sj;
				if(id[*i][si]!=0) k=w[id[*i][si]];
				if(id[*j][sj]!=0) k=max(k,w[id[*j][sj]]);
				if(!k) continue;
				res+=k;
			}
			else res+=w[id[*i][si]]+w[id[*j][sj]];
			ans=max(ans,res);
		}
	}
	printf("%lld\n",ans);
	return 0;
 }