求hack
查看原帖
求hack
427154
unsigned_short_int楼主2022/10/30 15:28

我的赛时代码碾过了InfOJ与洛谷的民间数据,但感觉复杂度不对。做法是预处理全源最短路,然后建新图,最后dfs枚举四个点。

#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;

const int N=2503,inf=1000000000;

int n,m,k;
long long p[N];
vector<int>e[N];

queue<int>q;
int dist[N][N];
bool vis[N];

vector<int>g[N];
long long f[N][4];

void dfs(int u,int dep,long long sum)
{
	vis[u]=true;
	sum+=p[u];
	f[u][dep]=sum;
	if(dep==3)
	{
		vis[u]=false;
		return;
	}
	
	for(int i=0,v,siz=g[u].size();i<siz;i++)
	{
		v=g[u][i];
		if(!vis[v] && f[v][dep+1]<sum+p[v])
			dfs(v,dep+1,sum);
	}
	vis[u]=false;
}

int main()
{
//	freopen("holiday.in","r",stdin);
//	freopen("holiday.out","w",stdout);
	ios::sync_with_stdio(false);
	
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(i!=j)
				dist[i][j]=inf;
	for(int i=2;i<=n;i++)
		cin>>p[i];
	for(int i=1,u,v;i<=m;i++)
	{
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	
	k++;
	
	for(int s=1;s<=n;s++)
	{
		q.push(s);
		vis[s]=true;
		while(!q.empty())
		{
			int u=q.front();
			q.pop();
			
			for(int i=0,v,siz=e[u].size();i<siz;i++)
			{
				v=e[u][i];
				if(!vis[v])
				{
					dist[s][v]=dist[s][u]+1;
					q.push(v);
					vis[v]=true;
				}
			}
		}
		
		memset(vis,0,sizeof vis);
	}
	
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
			if(dist[i][j]<=k)
			{
				g[i].push_back(j);
				g[j].push_back(i);
			}
	
	vis[1]=true;
	for(int i=0,siz=g[1].size();i<siz;i++)
		dfs(g[1][i],0,0);
	
	long long ans=0;
	for(int i=0,siz=g[1].size();i<siz;i++)
	{
		ans=max(ans,f[g[1][i]][3]);
	}
	cout<<ans;
	
	return 0;
}
2022/10/30 15:28
加载中...