逛公园

#include<bits/stdc++.h>
#define num ch-'0'
using namespace std;
typedef long long ll;
const int N=100000+10;
const int M=200000+10;
const int inf=(0x3f3f3f3f)*2;
int n,m,K,p;
int rd()
{
    int x=0;char ch;
    while(!isdigit(ch=getchar()));
    for(x=num;isdigit(ch=getchar());x=x*10+num);
    return x;
}
struct node{
    int nxt,to,val;
}bian[M];
struct kj{
    int nxt,to;
}edge[2*M*52],e0[M];
int hd[N],cnt1;
int pre[N],cnt2;
int pp[N],cnt3;

int has[N],tot;
int du[N*52];
int dis[N];
int q[N*2*52],l,r;
bool vis[N*52];
bool flag=true;
void add1(int x,int y,int z)
{
    bian[++cnt1].nxt=hd[x];
    bian[cnt1].to=y;
    bian[cnt1].val=z;
    hd[x]=cnt1;
}
void add2(int x,int y)
{
    edge[++cnt2].nxt=pre[x];
    edge[cnt2].to=y;
    pre[x]=cnt2;
}
void add3(int x,int y)
{
    e0[++cnt3].nxt=pp[x];
    e0[cnt3].to=y;
    pp[x]=cnt3;
}
bool jud()
{
    memset(vis,0,sizeof vis);
    l=1;r=0;
    //cout<<" tot "<<tot<<endl;
    for(int i=1;i<=tot;i++)
    {
        //cout<<" has "<<has[i]<<endl; 
        if(du[has[i]]==0) q[++r]=has[i];
    }
    while(l<=r)
    {
        int x=q[l++];
        vis[x]=1;
        for(int i=pp[x];i;i=e0[i].nxt)
        {
            int y=e0[i].to;
            du[y]--;
            if(du[y]==0) q[++r]=y;
        }
    }
    for(int i=1;i<=tot;i++)
    {
        if(vis[has[i]]!=1) return true;
    }
    return false;
}
void spfa()
{
    memset(vis,0,sizeof vis);
    for(int i=1;i<=n;i++) dis[i]=inf;
    dis[1]=0;
    vis[1]=1;
    l=1;r=0;
    q[++r]=1;
    while(l<=r)
    {
        int now=q[l++];
        vis[now]=0;
        for(int i=hd[now];i;i=bian[i].nxt)
        {
            int y=bian[i].to;
            if(dis[y]>dis[now]+bian[i].val)
            {
                dis[y]=dis[now]+bian[i].val;
                if(!vis[y])
                {
                    vis[y]=1;
                    q[++r]=y;
                }
            }
        }
    }
}
void work()
{
    memset(du,0,sizeof du);
    for(int x=1;x<=n;x++)
     for(int i=hd[x];i;i=bian[i].nxt)
     {
         int y=bian[i].to;
         int diss=dis[x]+bian[i].val-dis[y];
         //cout<<" kkk "<<x<<" to "<<y<<" : "<<diss<<endl;
        for(int j=0;j<=K-diss;j++)
        {
            int now=(x-1)*(K+1)+j;
            int too=(y-1)*(K+1)+j+diss;
            //cout<<now<<" "<<too<<endl;
            du[too]++;
            add2(now,too);
        }
     }
}
ll f[N*52];
void go()
{
    memset(f,0,sizeof f);
    memset(vis,0,sizeof vis);
    l=1;r=0;
    f[0]=1;
    q[++r]=0;
    while(l<=r)
    {
        int now=q[l++];
        //cout<<now<<endl;
        for(int i=pre[now];i;i=edge[i].nxt)
        {
            int y=edge[i].to;
            //cout<<" go "<<y<<endl;
            du[y]--;
            f[y]=(f[y]+f[now])%p;
            if(du[y]==0)
            {
                q[++r]=y;
                //cout<<" in "<<y<<endl;
            }
        }
    }
}
void clear()//warning!!!
{
    cnt1=cnt2=0;
    cnt3=0;
    flag=true;
    memset(du,0,sizeof du);
    memset(hd,0,sizeof hd);
    memset(pre,0,sizeof pre);
    memset(pp,0,sizeof pp);
    tot=0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T)
    {
        clear();    
        //n=rd(),m=rd(),K=rd(),p=rd();
        scanf("%d%d%d%d",&n,&m,&K,&p);
        int x,y,z;
        for(int i=1;i<=m;i++) {
            x=rd(),y=rd(),z=rd(),add1(x,y,z);// ,add1(y,x,z);
            if(z==0){
                has[++tot]=x,has[++tot]=y;
                add3(x,y);du[y]++;
            }
        }
        if(jud()){
            printf("-1\n");
        }
        else{
        spfa();
        //cout<<" diss: "<<endl;
        //for(int i=1;i<=n;i++) cout<<i<<" : "<<dis[i]<<endl;
        
        work();
        go(); 
        ll ans=0;
        for(int i=0;i<=K;i++)
        {
            int nn=(n-1)*(K+1)+i;
            ans=(ans+f[nn])%p;
        }
        printf("%lld\n",ans);
        }
        T--;
    }
    return 0;
}

hack:

1
7 10 3 10000
1 2 1
1 3 1
1 4 1
4 7 1
2 6 1
6 7 1
4 5 1
3 5 1
5 6 1
7 6 1

猜你喜欢

转载自www.cnblogs.com/Miracevin/p/9074429.html