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。
Sample Input
3 2 1 3
1 1 5 1
2 2 7 1
1 2 1
2 3 2
3 1 1
Sample Output
3
6
HINT
1到3:在时刻1使用第一种装置从1传送到2,花费时间3,再等待2单位时间,于时刻6使用第二种装置到达3,花费时间1。
前言
bzoj月赛爆炸了。。
这题想了很久都没有做出来。。
今早清北学堂的比赛心态爆炸了。。
来back一下昨天的题。。
题解
首先我们知道,你一个点肯定是越早到越好的。。
因为即使你说晚一点可能答案会优,但是我们可以原地等啊。。
这么简单的东西居然没有弄出来。。
昨晚一直在想拆点。。真是傻逼了。。
然后我们知道因为是mod ci,然后ci≤2000,所以一定会有循环节。。
于是我们可以很愉快地预处理出某个余数时刻到达这个点出去的最优代价
这一点昨晚还是想到了,也算是没有全线爆炸,然而这并没有什么luan用啊。。缺任意一个都会炸
然后预处理完之后就可以写dij跑最短路就可以nlogn复杂度了
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
typedef long long LL;
typedef pair<LL,int> P;
const LL N=2005;
const LL M=200005;
const LL MAX=1LL<<60;
LL f[N][N];
LL n,m,st,e;
LL mymax (LL x,LL y){return x>y?x:y;}
LL mymin (LL x,LL y){return x<y?x:y;}
struct qq
{
LL x,y,w,last;//用什么
}s[M];LL num,last[M];
void init (LL x,LL y,LL w)
{
num++;
s[num].x=x;s[num].y=y;s[num].w=w;
s[num].last=last[x];
last[x]=num;
}
LL cc[N];
LL g[M];
priority_queue<P,vector<P>,greater<P> >q;
int main()
{
num=0;memset(last,-1,sizeof(last));
scanf("%lld%lld%lld%lld",&n,&m,&st,&e);
for (LL u=1;u<=m;u++)
{
LL a,b,c,d;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
cc[u]=c;
for (LL i=0;i<c;i++)
{
f[u][i]=MAX;
for (LL j=0;j<c;j++) f[u][i]=mymin(f[u][i],1LL*(a*(i+j)+b)%c+d+j);//在这里等多久
}
}
for (LL u=1;u<=e;u++)
{
LL x,y,w;
scanf("%lld%lld%lld",&x,&y,&w);
init(x,y,w);
}
for (LL u=1;u<=n;u++) g[u]=MAX;
g[1]=st;q.push(P(g[1],1));
while (!q.empty())
{
P t=q.top();q.pop();
if (g[t.second]<t.first) continue;
LL x=t.second;
for (LL u=last[x];u!=-1;u=s[u].last)
{
LL y=s[u].y;
if (g[y]>g[x]+f[s[u].w][g[x]%cc[s[u].w]])
{
g[y]=g[x]+f[s[u].w][g[x]%cc[s[u].w]];
q.push(P(g[y],y));
}
}
}
for (LL u=2;u<=n;u++)
if (g[u]==MAX) printf("-1\n");
else printf("%lld\n",g[u]-st);
return 0;
}