其他分享
首页 > 其他分享> > 逛公园

逛公园

作者:互联网

传送门

解法:

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#define inf 2000000000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
int T,n,m,k,mod,ans;
int d[100010],dp[100010][55];
int tot,head[100010],tt,rev[100010];
bool cmp,vis[100010],v[100010][55];
queue<int> que;
struct EDGE
{
    int to,nxt,d;
}edge[200010],reve[200010];
void add(int u,int v,int d)
{
    edge[++tot].to=v;
    edge[tot].d=d;
    edge[tot].nxt=head[u];
    head[u]=tot;
}
void addr(int u,int v,int d)
{
    reve[++tt].to=v;
    reve[tt].d=d;
    reve[tt].nxt=rev[u];
    rev[u]=tt;
}
inline int read()
{
    int x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
        ch=getchar();
    while(ch>='0'&&ch<='9')
    {
        x=(x<<3)+(x<<1)+(ch^48);
        ch=getchar();
    }
    return x;
}
void spfa()
{
    d[n]=0;
    que.push(n);
    while(!que.empty())
    {
        int x=que.front();que.pop();
        vis[x]=0;
        for(int i=rev[x];i;i=reve[i].nxt)
        {
            int y=reve[i].to,dis=reve[i].d;
            if(d[y]>d[x]+dis)
            {
                d[y]=d[x]+dis;
                if(!vis[y]) vis[y]=1,que.push(y);
            }
        }
    }
}
int getdp(int x,int t)
{
    if(v[x][t]){v[x][t]=0;cmp=1;return 0;}
    if(dp[x][t]) return dp[x][t];
    v[x][t]=1;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int y=edge[i].to;
        int dis=t-(d[y]+edge[i].d-d[x]);
        if(dis<0||dis>k) continue;
        dp[x][t]=(dp[x][t]+getdp(y,dis))%mod;
        if(cmp){v[x][t]=0;return 0;}
    }
    v[x][t]=0;
    if(x==n&&t==0) dp[x][t]=1;//为了排除过终点的零环 终点初始值需要放在此处处理
    return dp[x][t];
}
int main()
{
    T=read();
    while(T--)
    {
        n=read(),m=read(),k=read(),mod=read();
        tot=1,tt=1;
        memset(head,0,sizeof(head));
        memset(rev,0,sizeof(rev));
        memset(d,0x3f,sizeof(d));
        memset(dp,0,sizeof(dp));
        rep(i,1,m)
        {
            int u=read(),v=read(),d=read();
            add(u,v,d);addr(v,u,d);
        }
        spfa();
        ans=0,cmp=0;
        dwn(i,k,0)
            ans=(ans+getdp(1,i))%mod;
        if(cmp) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}

标签:int,tot,read,edge,逛公园,include,dp
来源: https://www.cnblogs.com/MYsBlogs/p/11068548.html