记录编号 493078 评测结果 AAAAAAATAT
题目名称 [NOIP 2017]逛公园 最终得分 80
用户昵称 Gravataryyb 是否通过 未通过
代码语言 C++ 运行时间 10.772 s
提交时间 2018-03-29 21:25:19 内存使用 50.10 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 222222
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
struct Line{int v,next,w;}e[MAX*4];
int h[MAX],cnt=1,tim,top;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
int S[MAX],dfn[MAX],low[MAX];
bool vis[MAX],Ins[MAX],fl;
int dis1[MAX],dis2[MAX];
int n,m,K,P;
void init()
{
	fl=true;
	memset(h,0,sizeof(h));cnt=1;tim=top=0;
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	memset(dis1,63,sizeof(dis1));
	memset(dis2,63,sizeof(dis2));
}
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >Q;
void Dijkstra(int S,int *dis,int opt)
{
	while(!Q.empty())Q.pop();
	Q.push(make_pair(0,S));
	memset(vis,0,sizeof(vis));
	int u,d;
	while(!Q.empty())
	{
		u=Q.top().second;d=Q.top().first;Q.pop();
		if(vis[u])continue;vis[u]=true;dis[u]=d;
		for(int i=h[u];i;i=e[i].next)
			if((i&1)^opt)
				if(!vis[e[i].v])
					Q.push(make_pair(d+e[i].w,e[i].v));;
	}
}
void Tarjan(int u)
{
	dfn[u]=low[u]=++tim;
	S[++top]=u;Ins[u]=true;
	for(int i=h[u];i;i=e[i].next)
		if((i&1)&&!e[i].w)
		{
			int v=e[i].v;
			if(!dfn[v])Tarjan(v),low[u]=min(low[u],low[v]);
			else if(Ins[v])low[u]=min(low[u],dfn[v]);
		}
	if(low[u]==dfn[u])
	{
		int v,size=0,ltp=top;
		do{v=S[top--];Ins[v]=false;++size;}while(u!=v);
		if(size!=1&&fl)
		{
			for(int i=ltp;i>top;--i)
				if(dis1[S[i]]+dis2[S[i]]<=dis1[n]+K)fl=false;
		}
	}
}
int f[55][MAX];
int SPFA(int u,int d)
{
	if(f[d][u])return f[d][u];
	for(int i=h[u];i;i=e[i].next)
		if(~i&1)
		{
			int v=e[i].v;
			int dd=d-e[i].w+dis1[u]-dis1[v];
			if(dd<0)continue;
			f[d][u]=(f[d][u]+SPFA(v,dd))%P;
		}
	return f[d][u];
}
int main()
{
	freopen("2017park.in","r",stdin);
	freopen("2017park.out","w",stdout);
	int T=read();
	while(T--)
	{
		init();
		n=read();m=read();K=read();P=read();
		for(int i=1;i<=m;++i)
		{
			int u=read(),v=read(),w=read();
			Add(u,v,w);Add(v,u,w);
		}
		Dijkstra(1,dis1,0);
		Dijkstra(n,dis2,1);
		for(int i=1;i<=n;++i)if(!dfn[i])Tarjan(i);
		if(!fl){puts("-1");continue;}
		memset(f,0,sizeof(f));
		f[0][1]=1;
		int ans=0;
		for(int i=0;i<=K;++i)ans=(ans+SPFA(n,i))%P;
		printf("%d\n",ans);
	}
	return 0;
}