[NOIP2017] solution to a problem the park

I will not even D1T3 I finished the league

 

Title Description

Policy-making students especially like the park. Park can be seen as an  N  point  M  has the configuration of FIG edges, and heavy and not self-loop edge. Wherein 1 point is the park entrance,  N  number park exit point, each side has a non-negative weight value that represents the policy plan after this time it will take sides.

Policy-making will go to the park every day, he always went from 1 point, from  N  out of the dot.

Policy-making like new things, it does not want the park for two days exactly the same route, while making policy or a particular love for the boy to learn, every day it does not want to spend too much time in the park on this matter. If the point 1 to  N  dots of the shortest length  D  , then making only the like making no longer than  d + K  route.

Policy-making students want to know the route to meet the conditions of a total of how many you can help it do?

To avoid excessive output, the answer to the  P  modulo.

If there are an infinite number of legitimate route, output  -1  .


Entry

The first row contains an integer  T  , represents the number of data sets.

Next  T  sets of data, for each set of data: The first line contains four integers  N , M , K , P, between each two integers separated by a space.

Next  M  rows, each row of three integers  A I , B I , C I  , the representative number  A I , B I  has a weight of between one point  C I  directed edge, each between two integers separated by a space (there may be 0 side).

To 100% of the data, P ≤ 1 ≦ 10 . 9 , N ≤ 100000, 200000 ≤ M,. 1 ≤ AI, BI ≤ N, 0 ≤ CI ≤ 1000.


Export

Output file contains  T  lines, each integer represents the answer.

 

 

 

$Solution:$

30 points is the shortest bare spfa count (estimate took to put me on the break B)

It notes that data K range is very small, considering the state put it ran dp.

First of contravened Figure shortest run about, so that we get the shortest distance to all points of n.

What is the use? When the transfer of know if you can go this side, would be "to walk than the shortest amount of" make much contribution.

Provided $ F [x] [k] n $ is the distance x to x is no more than the shortest distance n + k is the number of programs, the transfer can be obtained:

$ F [x] [k] = \ sum f [y] [k- (d (y, n) -d (x, n) + w [i])] $, $ d (y, n) $ represents y n is the length of the shortest.

Memory of the search. With a two-dimensional array about whether the state record in the stack, to judge 0 ring.

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define pa pair<int,int>
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
typedef long long ll;
const int N=1e5+5,M=4e5+5;
int K,T,n,m,dis[N],v[N],ins[N][55];
ll mod,f[N][55];
namespace G
{
    int to[M],head[N],nxt[M],w[M],tot;
    void add(int x,int y,int z)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
        w[tot]=z;
    }
}
namespace rev
{
    int to[M],head[N],nxt[M],w[M],tot;
    void add(int x,int y,int z)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
        w[tot]=z;
    }
}
void dj()
{
    priority_queue<pa> q;
    memset(dis,0x3f,sizeof(dis));
    memset(v,0,sizeof(v));
    dis[n]=0;
    q.push(make_pair(0,n));
    while(!q.empty())
    {
        int x=q.top().second;q.pop();
        if(v[x])continue;
        v[x]=1;
        for(int i=rev::head[x];i;i=rev::nxt[i])
        {
            int y=rev::to[i];
            if(dis[y]>dis[x]+rev::w[i])
                dis[y]=dis[x]+rev::w[i],q.push(make_pair(-dis[y],y));
        }
    }
}
ll dfs(int x,int k)
{
    if(ins[x][k])return -1;
    if(f[x][k])return f[x][k];
    ins[x][k]=1;
    if(x==n)f[x][k]=1;
    for(int i=G::head[x];i;i=G::nxt[i])
    {
        int y=G::to[i],now=dis[y]-dis[x]+G::w[i];
        if(now<=k)
        {
            ll ret=dfs(y,k-now);
            if(ret==-1)return f[x][k]=-1;
            (f[x][k]+=ret)%=mod;
        }
    }
    ins[x][k]=0;
    return f[x][k];
}
void work()
{
    n=read();m=read();K=read();mod=read();
    for(int i=1;i<=n;i++)
        G::head[i]=rev::head[i]=v[i]=0;
    G::tot=rev::tot=0;
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read(),z=read();
        G::add(x,y,z);
        rev::add(y,x,z);
    }
    dj();
    memset(f,0,sizeof(f));
    memset(ins,0,sizeof(ins));
    printf("%lld\n",dfs(1,K));
}
int main()
{
    T=read();
    while(T--)work();
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/Rorschach-XR/p/11670684.html