CF553E Kyoya and Train

2024-04-30 23:08
文章标签 train kyoya cf553e

本文主要是介绍CF553E Kyoya and Train,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

给定一张 n 个点 m 条边的无重边无自环的有向图,你要从 1 号点到 n 号点去。
如果你在 t 时刻之后到达n 号点,你要交 x 元的罚款。
每条边从 a i a_i ai b i b_i bi ,走过它需要花费 c i c_i ci元,多次走过同一条边需要多次花费。
走过每条边所需的时间是随机的,对于 k∈[1,t], p i , k 1 0 5 \dfrac{p_{i,k}}{10^5} 105pi,k 表示走过第 i 条边需要时间 k 的概率。因此如果多次走过同一条边,所需的时间也可能不同。
你希望花费尽可能少的钱(花费与罚款之和)到达 n 号点,因此每到达一个点,你可能会更改原有的计划。
求在最优决策下,你期望花费的钱数。
n ≤ 50 , m ≤ 100 , t ≤ 2 × 1 0 4 , x , c i ≤ 1 0 6 , ∑ k = 1 t p i , k = 1 0 5 n \leq 50,m \leq 100,t \leq 2 \times 10^4,x,c_i \le 10^6 ,\sum_{k=1}^t p_{i,k} = 10^5 n50m100t2×104x,ci106,k=1tpi,k=105 ,答案精度误差 ≤ 1 0 − 6 \leq 10^{-6} 106


Solution

FFT优化spfa多状态转移

正着设初始状态并不对劲,正难则反。
算了 我⑧说了 看这里罢

还是很能体现概率期望的灵活性。

转移时其实只有后面的时间能够影响前面的时间,其实是一个分层转移。那么我们可以通过CDQ分治时间计算,时间复杂度为 O ( m t l o g 2 t ) O(mtlog^2t) O(mtlog2t)

这里写的是sb做法,直接FFT转移SPFA,时间复杂度 O ( n m t l o g t ) O(nmtlogt) O(nmtlogt)
dijkstra的话因为无法有效比较两个状态的优劣(第二维时间太多)而没法写


Code

#include<bits/stdc++.h>
using namespace std;
struct edge{int y,z,nxt;
}e[110];
int head[60],cnt;
void add(int x,int y,int z){cnt++;e[cnt].y=y;e[cnt].z=z;e[cnt].nxt=head[x];head[x]=cnt;
}
long long d[60];
bool vis[60];
struct data{int x;long long s;bool operator <(const data &v)const{return s>v.s;}
};
priority_queue<data>q1;
const double pi=acos(-1.0);
int n,m,t,S,bit,limit=1,rev[200010];
struct cp{double x,y;cp(double xx=0,double yy=0){x=xx,y=yy;}
}a[200010],b[200010],c[200010];
double p[110][200010],dis[60][200010];
cp operator + (cp u,cp v){return cp(u.x+v.x,u.y+v.y);		
}
cp operator - (cp u,cp v){return cp(u.x-v.x,u.y-v.y);		
}
cp operator * (cp u,cp v){return cp(u.x*v.x-u.y*v.y,u.x*v.y+u.y*v.x);	
}
void dijkstra(){for(int i=1;i<n;i++) d[i]=1e15;q1.push((data){n,0});while(!q1.empty()){data x=q1.top();q1.pop(),vis[x.x]=0;for(int i=head[x.x];i;i=e[i].nxt){int y=e[i].y,z=e[i].z;if(d[y]>d[x.x]+z){d[y]=d[x.x]+z;if(!vis[y]){q1.push((data){y,d[y]});vis[y]=true;}}}}//for(int i=1;i<=n;i++)//cout<<i<<" "<<d[i]<<endl;
}
void FFT(cp *A,int type){for(int i=0;i<limit;i++)if(i<rev[i]) swap(A[i],A[rev[i]]);for(int mid=1;mid<limit;mid<<=1){cp wn(cos(pi/mid),type*sin(pi/mid));for(int r=mid<<1,j=0;j<limit;j+=r){cp w(1,0);for(int k=0;k<mid;k++,w=w*wn){cp x=A[j+k],y=w*A[j+mid+k];A[j+k]=x+y,A[j+mid+k]=x-y;}	}}if(type==-1)for(int i=0;i<limit;i++)A[i].x/=limit;
}
void mul(double *A,double *B){for(int i=0;i<=2*t;i++)a[i]=cp(A[i],0),b[i]=cp(B[i],0);//,cout<<a[i].x<<" "<<b[i].x<<endl;;for(int i=2*t+1;i<limit;i++)a[i]=b[i]=cp(0,0);FFT(a,1),FFT(b,1);for(int i=0;i<limit;i++)c[i]=a[i]*b[i]; FFT(c,-1);
}
queue<int>q2; 
void spfa(){for(int i=1;i<=n;i++){for(int j=0;j<=t;j++)dis[i][j]=1e15;for(int j=t+1;j<=2*t;j++)dis[i][j]=d[i]+S; }for(int j=0;j<=t;j++)dis[n][j]=0;q2.push(n);while(!q2.empty()){int x=q2.front();q2.pop(),vis[x]=0;for(int i=head[x];i;i=e[i].nxt){int y=e[i].y,z=e[i].z;mul(dis[x],p[i]);bool flag=false;for(int j=0;j<=t;j++)if(dis[y][j]>c[t+j+1].x+z){dis[y][j]=c[t+j+1].x+z;flag=true;}if(flag&&!vis[y]){q2.push(y);vis[y]=1;}}}
}
int main(){int x,y,z;scanf("%d%d%d%d",&n,&m,&t,&S);for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);add(y,x,z);for(int j=1;j<=t;j++){scanf("%lf",&p[i][j]);p[i][j]/=100000;}reverse(p[i]+1,p[i]+t+1);}dijkstra();while(limit<=4*t)limit<<=1,bit++;for(int i=0;i<limit;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));spfa();//for(int i=0;i<=2*t;i++)printf("%.10lf",dis[1][0]);
}

这篇关于CF553E Kyoya and Train的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/950160

相关文章

OpenStack离线Train版安装系列—3控制节点-Keystone认证服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack离线Train版安装系列—2计算节点-环境准备

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack离线Train版安装系列—1控制节点-环境准备

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack离线Train版安装系列—0制作yum源

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack离线Train版安装系列—10.控制节点-Heat服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack离线Train版安装系列—11.5实例使用-Cinder存储服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

Tensorflow 中train和test的batchsize不同时, 如何设置: tf.nn.conv2d_transpose

大家可能都知道, 在tensorflow中, 如果想实现测试时的batchsize大小随意设置, 那么在训练时, 输入的placeholder的shape应该设置为[None, H, W, C]. 具体代码如下所示: # Placeholders for input data and the targetsx_input = tf.placeholder(dtype=tf.float32, s

tf.train.batch 和 tf.train.batch_join的区别

先看两个函数的官方文档说明 tf.train.batch官方文档地址: https://www.tensorflow.org/api_docs/python/tf/train/batch tf.train.batch_join官方文档地址: https://www.tensorflow.org/api_docs/python/tf/train/batch_join tf.train.ba

tf.train.ExponentialMovingAverage用法和说明

在这篇博客中对tf.train.ExponentialMovingAverage讲的很清楚,这里主要补充几点说明: 第一点: 当程序执行到 ema_op = ema.apply([w]) 的时候,如果 w 是 Variable, 那么将会用 w 的初始值初始化 ema 中关于 w 的 ema_value,所以 emaVal0=1.0。如果 w 是 Tensor的话,将会用 0.0 初始化。

tf.train.exponential_decay(学习率衰减)

#!/usr/bin/env python3# -*- coding: utf-8 -*-'''学习率较大容易搜索震荡(在最优值附近徘徊),学习率较小则收敛速度较慢,那么可以通过初始定义一个较大的学习率,通过设置decay_rate来缩小学习率,减少迭代次数。tf.train.exponential_decay就是用来实现这个功能。'''__author__ = 'Zhang Shuai'i