【题解】Luogu P5340 [TJOI2019]大中锋的游乐场

原题传送门

没想到省选也会出这种题??!

实际就是一个带有限制的最短路

因为(k<=10),所以我们珂以暴力将每个点的权值分为[-k,k],为了方便我们珂以转化成[0,2k],将汉堡的权值记为1,可乐的权值记为-1,最短路即可,如果发现不合理的就果断扔掉即可(不知道有没有好事之徒用SPFA写)

#include <bits/stdc++.h>
#define N 10005
#define pi pair<int,int>
#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline int Min(register int a,register int b)
{
	return a<b?a:b;
}
int T,n,m,k,c[N],s,t,dis[N][21],vis[N][21];
vector<pi> e[N];
priority_queue<pi,vector<pi>,greater<pi> > Q;
int main()
{
	T=read();
	while(T--)
	{
		n=read(),m=read(),k=read();
		for(register int i=0;i<n;++i)
			e[i].clear(),c[i]=(read()<<1)-3;
		for(register int i=0;i<m;++i)
		{
			int x=read()-1,y=read()-1,z=read();
			e[x].push_back(make_pair(y,z));
			e[y].push_back(make_pair(x,z));
		}
		s=read()-1,t=read()-1;
		memset(dis,63,sizeof(dis));
		memset(vis,0,sizeof(vis));
		Q.push(make_pair(dis[s][k+c[s]]=0,n*(k+c[s])+s));
		while(!Q.empty())
		{
			int u=Q.top().second%n,x=Q.top().second/n;
			Q.pop();
			if(vis[u][x])
				continue;
			vis[u][x]=1;
			for(register int t=0;t<e[u].size();++t)
			{
				int v=e[u][t].first,w=e[u][t].second,y=x+c[v];
				if(y>=0&&y<=k<<1&&dis[v][y]>dis[u][x]+w)
					dis[v][y]=dis[u][x]+w,Q.push(make_pair(dis[v][y],n*y+v));
			}
		}
		int ans=dis[t][0];
		for(register int i=1;i<=k<<1;++i)
			ans=Min(ans,dis[t][i]);
		write(ans>1e9?-1:ans),puts("");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10940573.html