ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

太空中一共有n座星球,它们之间可以通过空间传送装置进行转移。空间传送装置分为m种,第i种装置可以用4个参
数a_i,b_i,c_i,d_i来描述。因为时空抖动的问题,在非整数时刻禁止使用空间传送装置。如果在整数s时刻使用装
置,那么需要花费((a_i*s+b_i) mod c_i)+d_i单位时间才能完成传送。现在是s时刻,小Q位于1号星球,请写一个
程序计算从1号星球到每个星球最少需要的时间。

Input

第一行包含4个正整数n,m,s,e(2<=n<=100000,1<=m<=50,1<=s<=2000,1<=e<=200000)
分别表示星球的个数、空间传送装置的种类数、当前的时间以及空间传送装置的个数。
接下来m行,每行4个正整数a_i,b_i,c_i,d_i(1<=a_i,b_i,c_i,d_i<=2000),依次描述每种装置的参数。
接下来e行,每行3个正整数u_i,v_i,w_i(1<=u_i,v_i<=n,u_i!=v_i,1<=w_i<=m)
表示从星球u_i可以使用第w_i种装置单向传送到星球v_i。

Output

输出n-1行,每行一个整数,第i行表示从1到i+1的最少所需时间,若无解输出-1。
O(mc)递推预处理出每种边在模c意义下x时刻的边长,然后做普通的最短路。
#include<bits/stdc++.h>
typedef unsigned int u32;
const int N=1e5+7;
int _(){int x;scanf("%d",&x);return x;}
int n,m,e;
struct edge{
    int to,tp;
    edge*nx;
}es[N*2],*ep=es,*e0[N];
struct node{
    u32 w,l;
    bool operator<(const node&w)const{return l>w.l;}
};
std::priority_queue<node>q;
u32 l[N];
void mins(u32&a,u32 b){if(a>b)a=b;}
struct etype{
    u32 a,b,c,d,ds[2007];
    void read(){
        a=_(),b=_(),c=_(),d=_();
        for(u32 i=0;i<c;++i)ds[i]=(a*i+b)%c;
        for(int t=0;t<2;++t){
            ds[c]=ds[0];
            for(u32 i=c;i;--i)mins(ds[i-1],ds[i]+1);
        }
        for(u32 i=0;i<c;++i)ds[i]+=d;
    }
    u32 operator()(u32 x){return ds[x%c];}
}ts[55];
int main(){
    n=_();m=_();l[1]=_();e=_();
    for(int i=1;i<=m;++i)ts[i].read();
    for(int i=1,a,b,c;i<=e;++i){
        a=_(),b=_(),c=_();
        *ep=(edge){b,c,e0[a]};e0[a]=ep++;
    }
    for(int i=2;i<=n;++i)l[i]=UINT_MAX;
    q.push((node){1,l[1]});
    while(q.size()){
        node w=q.top();q.pop();
        if(w.l!=l[w.w])continue;
        for(edge*i=e0[w.w];i;i=i->nx){
            u32 u=i->to,d=ts[i->tp](w.l);
            if(l[u]>w.l+d)q.push((node){u,l[u]=w.l+d});
        }
    }
    for(int i=2;i<=n;++i)l[i]==UINT_MAX?puts("-1"):printf("%u\n",l[i]-l[1]);
    return 0;
}
View Code
posted on 2017-10-19 15:48  nul  阅读(289)  评论(0编辑  收藏  举报