标签:print topsort define [1] sha read ext ring 总数
最短路+topsort+dp
求出1到所有点的单源最短路。
所有edge(x,y)满足dis[x]+w[e]≥dis[y],
则大于最短路的值不会减少。
设状态f[i][j]为到达i点时经过的长度为dis[i]+j(j≤k)的路径数.
因此对于一个节点可以扩展出其他k个新结点.
分别表示不同的距离(dis[x]~dis[x]+k).
这就是一个分层图,同层的点之间进行转移,或者向上层的点进行转移,不会向下层的点进行转移。
那么是在分层图上求路径总数。
自然 f[1][0]=1,
做topsort时进行dp转移。
topsort后
一个点没有deg,它的f之和值即为路径总数.
否则,它的路径总数为无穷.
统计sigma(f[n][0...k])。
总时间复杂度 O(T(mlogn+mk))
#include<stdio.h>
#include<algorithm>
#include<ctype.h>
#include<string.h>
#include<queue>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
#define VIS(now) for(register int e=las[now];e;e=nxt[e])
#define pos(x,y) (x+(y)*n)
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
using std::priority_queue;
using std::pair;
using std::make_pair;
const int N=800011,M=1600011,inf=(1<<30);
priority_queue<pa>heap;
inline char nc(){
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
int ret=0;char ch=nc();
while(!isdigit(ch))ch=nc();
while(isdigit(ch))ret=((ret+(ret<<2))<<1)+(ch^‘0‘),ch=nc();
return ret;
}
int nxt[M],las[N],to[M],w[M],dis[N],vis[N],l[N*51],r[N*51],t[M*51],deg[N*51],f[N*51],que[N*51];
int tot,cnt,n,m,k,p,T,now,ans,head,tail;
inline void add(int x,int y,int z){
nxt[++tot]=las[x];las[x]=tot;to[tot]=y;w[tot]=z;
}
inline void DJ(){
int now;
dis[1]=0;
heap.push(mp(0,1));
while(!heap.empty()){
now=heap.top().second;
heap.pop();
if(vis[now])continue;
vis[now]=1;
VIS(now)
if(dis[now]+w[e]<dis[to[e]]){
dis[to[e]]=dis[now]+w[e];
heap.push(mp(-dis[to[e]],to[e]));
}
}
}
int x,y,z;
int main(){
T=read();
die:;
while(T--){
ans=tot=cnt=0;
n=read();m=read();k=read();p=read();
FOR(i,1,n)las[i]=0,dis[i]=inf,vis[i]=0;
FOR(i,1,pos(n,k))f[i]=0,deg[i]=0;
f[1]=1;
while(m--)x=read(),y=read(),z=read(),add(x,y,z);
DJ();
FOR(i,1,n)
FOR(j,0,k){
l[pos(i,j)]=cnt+1;
VIS(i)
if(j+dis[i]+w[e]-dis[to[e]]<=k)
++deg[t[++cnt]=pos(to[e],j+dis[i]+w[e]-dis[to[e]])];
r[pos(i,j)]=cnt;
}
head=1,tail=0;
FOR(i,1,pos(n,k))
if(!deg[i])
que[++tail]=i;
while(head<=tail){
now=que[head++];
FOR(i,l[now],r[now]){
--deg[t[i]];
f[t[i]]+=f[now];
if(f[t[i]]>=p)f[t[i]]-=p;
if(!deg[t[i]])que[++tail]=t[i];
}
}
FOR(i,0,k){
if(deg[pos(n,i)]){
puts("-1");
goto die;
}
ans+=f[pos(n,i)];
if(ans>=p)ans-=p;
}
printf("%d\n",ans);
}
return 0;
}
标签:print topsort define [1] sha read ext ring 总数
原文地址:http://www.cnblogs.com/Stump/p/7896595.html