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

Posted yzhang-rp-inf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解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;
}

以上是关于题解Luogu P5340 [TJOI2019]大中锋的游乐场的主要内容,如果未能解决你的问题,请参考以下文章

题解Luogu P5339 [TJOI2019]唱跳rap和篮球

题解Luogu P5342 [TJOI2019]甲苯先生的线段树

题解 luogu 3857 [TJOI2008]彩灯 (线性基)

luogu P5337 [TJOI2019]甲苯先生的字符串

luogu题解 P3763 [TJOI2017]DNA

luogu P3879 [TJOI2010]阅读理解 题解