记录编号 |
493078 |
评测结果 |
AAAAAAATAT |
题目名称 |
[NOIP 2017]逛公园 |
最终得分 |
80 |
用户昵称 |
yyb |
是否通过 |
未通过 |
代码语言 |
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;
}