题目
题目大意
就是给出一个n个点的有向图,
每条边的边权是随时间的变化而变化。
求从1出发的,到所有点的最短路。
题解
对于每一条边,
通过它到达下一个点的时间就是要加上它等车的时间。
就是在spfa上面的边权位置稍微修改一下就可以了。
code
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 200003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define pi 3.1415926535897932384626433832795
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
int nxt[N*2],to[N*2],k[N*2],b[N*2],lst[N],tot;
int n,m,s,t[N];
int q[N*10],f[N],l,r,x,y,st,v,w;
bool bz[N];
void ins(int x,int y,int t1,int t2)
{
nxt[++tot]=lst[x];
to[tot]=y;
lst[x]=tot;
k[tot]=t1;
b[tot]=t2;
}
int main()
{
freopen("bus.in","r",stdin);
freopen("bus.out","w",stdout);
read(n);read(m);
for(int i=1;i<=m;i++)
{
read(s);read(t[1]);
for(int j=2;j<=s;j++)read(t[j]),ins(t[j-1],t[j],s,j-2);
ins(t[s],t[1],s,s-1);
}
memset(f,127,sizeof(f));
memset(bz,1,sizeof(bz));
for(f[q[r=1]=1]=l=bz[1]=0;l<r;)
{
st=f[x=q[++l]];
for(int i=lst[x];i;i=nxt[i])
{
y=to[i];w=st/k[i];
if(st%k[i]>b[i])w++;
v=w*k[i]+b[i]+1;
if(f[y]>v)
{
f[y]=v;
if(bz[y])bz[q[++r]=y]=0;
}
}
bz[x]=1;
}
for(int i=2;i<=n;i++)
if(f[i]<f[0])write(f[i]),P(' ');
else P('-'),P('1'),P(' ');
return 0;
}