zoukankan      html  css  js  c++  java
  • luogu P5340 [TJOI2019]大中锋的游乐场

    传送门

    要求经过路径汉堡的点和可乐的点个数之差绝对值(le k),所以可以考虑dp,(f_{i,j})表示到点(i),汉堡的点个数减可乐的点的个数为(j)的最短距离,注意一下负下标处理,然后跑个dij就完事了

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #define LL long long
    #define db double
    
    using namespace std;
    const int N=1e4+10,M=1e5+10,mod=998244353;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[M<<1],nt[M<<1],w[M<<1],hd[N],tot;
    void add(int x,int y,int z)
    {
        ++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;
        ++tot,to[tot]=x,nt[tot]=hd[y],w[tot]=z,hd[y]=tot;
    }
    int n,m,kk,a[N];
    LL di[N][21];
    struct node
    {
        int x,k;
        LL d;
        bool operator < (const node &bb) const {return d>bb.d;}
    };
    priority_queue<node> q;
    
    int main()
    {
        int T=rd();
        while(T--)
        {
            n=rd(),m=rd(),kk=rd();
            for(int i=1;i<=n;++i) a[i]=rd()&1?-1:1;
            memset(hd,0,sizeof(hd)),tot=1;
            while(m--)
            {
                int x=rd(),y=rd(),z=rd();
                add(x,y,z);
            }
            memset(di,0x3f,sizeof(di));
            int ps=rd(),pt=rd();
            if(kk+a[ps]>=0&&kk+a[ps]<=kk+kk)
                q.push((node){ps,kk+a[ps],di[ps][kk+a[ps]]=0});
            while(!q.empty())
            {
                int x=q.top().x,k=q.top().k;
                LL d=q.top().d;
                q.pop();
                if(d>di[x][k]) continue;
                for(int i=hd[x];i;i=nt[i])
                {
                    int y=to[i],nk=k+a[y];
                    if(nk>=0&&nk<=kk+kk&&di[y][nk]>di[x][k]+w[i])
                        q.push((node){y,nk,di[y][nk]=di[x][k]+w[i]});
                }
            }
            LL ans=1ll<<50;
            for(int i=0;i<=kk+kk;++i) ans=min(ans,di[pt][i]);
            ans<(1ll<<50)?printf("%lld
    ",ans):puts("-1");
        }
        return 0;
    }
    
  • 相关阅读:
    215. Kth Largest Element in an Array
    B:魔兽世界之一:备战
    218. The Skyline Problem
    编程作业: 编程作业—类和对象
    239. Sliding Window Maximum
    313. Super Ugly Number
    hdu3068 manacher模板题
    fzu1901 kmp
    hdu2609 最小表示法
    hdu3374 kmp+最小表示法
  • 原文地址:https://www.cnblogs.com/smyjr/p/10841243.html
Copyright © 2011-2022 走看看