正题
大意
有一个大人物,它要从经过一些地方,他所在的路会被封闭(不可以进入,可以出)。你要从一个点到到另一个点,求最短时间。
解题思路
求出每条路的封闭时间,然后SPFA
代码
#include<cstdio>
#include<cstring>
using namespace std;
struct line{int x,y,w,next,en,st;
}a[20001];
int p[1001],state[1001],f[1001],n,s,e,mn,m,t,g,ww,xx,yy,head,tail,ls[1001];
bool v[1001];
void spfa()
{state[1]=s;v[s]=true;memset(f,127/3,sizeof(f));f[s]=t;head=0;tail=1;do{head=head%n+1;int q=ls[state[head]];while (q){if (f[a[q].x]+a[q].w<f[a[q].y] && (f[a[q].x]<a[q].st || f[a[q].x]>=a[q].en))//直接走{f[a[q].y]=f[a[q].x]+a[q].w;if (!v[a[q].y]){tail=tail%n+1;state[tail]=a[q].y;v[a[q].y]=true;}}else if (f[a[q].x]>=a[q].st && f[a[q].x]<a[q].en && a[q].en+a[q].w<f[a[q].y])//等道路开启{f[a[q].y]=a[q].en+a[q].w;if (!v[a[q].y]){tail=tail%n+1;state[tail]=a[q].y;v[a[q].y]=true;}}q=a[q].next;}v[state[head]]=false;}while (head!=tail);
}
int main()
{scanf("%d%d%d%d%d%d",&n,&mn,&s,&e,&t,&g);for (int i=1;i<=g;i++){scanf("%d",&p[i]);}for (int i=1;i<=mn;i++){scanf("%d%d%d",&xx,&yy,&ww);a[++m].x=xx;a[m].y=yy;a[m].next=ls[xx];a[m].w=ww;ls[xx]=m;a[++m].y=xx;a[m].x=yy;a[m].next=ls[yy];a[m].w=ww;ls[yy]=m;//插入一条边}ww=0;for (int i=1;i<g;i++){int q=ls[p[i]];while (a[q].y!=p[i+1])q=a[q].next;a[q].st=ww;ww+=a[q].w;a[q].en=ww;q=ls[p[i+1]];while (a[q].y!=p[i])q=a[q].next;a[q].st=ww-a[q].w;a[q].en=ww;//求路什么时间被封闭}spfa();printf("%d",f[e]-t);
}