Atcoder Beginner Contest 164 E Two Currencies(拆点+最短路)
题意:有 \(n\) 个城市,它们由 \(m\) 条双向道路连接,保证它们能够彼此到达。第 \(i\) 条道路连接 \(u_i,v_i\),需要花费 \(x_i\) 个银币,耗费 \(t_i\) 秒的时间。每个城市处都有兑换银币处,第 \(i\) 个城市中你可以用 \(1\) 个金币兑换 \(c_i\) 个银币,可以兑换无限次,不过兑换 \(1\) 次需要花费 \(d_i\) 秒的时间。你一开始在 \(1\) 号城市,有 \(s\) 个银币和无限多的金币,求到其它城市需要耗费的最小时间。
\(1 \leq n \leq 50\),\(1 \leq x_i \leq 50\),\(1 \leq t_i,d_i \leq 10^9\),\(1 \leq s,c_i \leq 10^9\)。
abc 的 F 都切不掉,只好水 E 的题解了
观察到虽然 \(s,c_i\) 很大,但是 \(x_i\) 只有 \(50\)。这也就意味着到其它需要花费的银币绝对不会超过 \(49 \times 50=2450\),所以如果当前银币数超过 \(2450\),就可以将它看作 \(2450\)。
我们将“当前位于城市 \(i\),手中有 \(j\) 个银币”看成一个点 \((i,j)\),那么我们可以重新建一张图,两个状态 \((x_1,y_1),(x_2,y_2)\) 之间有一条有向边当且仅当 \((x_1,y_1)\) 可以到达 \((x_2,y_2)\),边权为花费的时间。
建图:
- \((i,j) \rightarrow (i,j+c_i)\),边权为 \(d_i\)
- \((i,j) \rightarrow (k,j-x_p)\),边权为 \(t_p\),其中 \((i,k)\) 之间有边,编号为 \(p\),\(j \geq x_p\)
跑一遍 dijkstra,起点为 \((1,s)\),点 \(u\) 的答案就是 \(\min\ (1,s)\) 到 \((u,i)\) 的距离。
大概是网络流基本建图模型?(雾
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define giveup(...) return printf(__VA_ARGS__),0;
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define mask(a) (1ll<<(a))
#define maskx(a,x) ((a)<<(x))
#define _bit(a,x) (((a)>>(x))&1)
#define _sz(a) ((int)(a).size())
#define filei(a) freopen(a,"r",stdin);
#define fileo(a) freopen(a,"w",stdout);
#define fileio(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define put(x) putchar(x)
#define eoln put('\n')
#define space put(' ')
#define y1 y_chenxiaoyan_1
#define y0 y_chenxiaoyan_0
#define int long long
typedef pair<int,int> pii;
inline int read(){
int x=0,neg=1;char c=getchar();
while(!isdigit(c)){
if(c=='-') neg=-1;
c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*neg;
}
inline void print(int x){
if(x<0){
putchar('-');
print(abs(x));
return;
}
if(x<=9) putchar(x+'0');
else{
print(x/10);
putchar(x%10+'0');
}
}
inline int qpow(int x,int e,int _MOD){
int ans=1;
while(e){
if(e&1) ans=ans*x%_MOD;
x=x*x%_MOD;
e>>=1;
}
return ans;
}
int n=read(),m=read(),s=read(),c[55],d[55];
struct edge{
int u,v,w;
edge(){/*ycxakioi*/}
edge(int _u,int _v,int _w){
u=_u;v=_v;w=_w;
}
};
const int MAGIC=2456;
inline int id(int x,int y){
return x*(MAGIC+1)+y;
}
vector<edge> g[55*2555];
int dist[55*2555],vis[25*2555];
priority_queue<pii,vector<pii>,greater<pii> > q;
signed main(){
fz(i,1,m){
int u,v,a,b;cin>>u>>v>>a>>b;
fz(j,0,MAGIC){
if(j>=a){
g[id(u,j)].push_back(edge(id(u,j),id(v,j-a),b));
g[id(v,j)].push_back(edge(id(v,j),id(u,j-a),b));
}
}
}
fz(i,1,n) c[i]=read(),d[i]=read();
fz(i,1,n){
fz(j,0,MAGIC-1){
int cur=j+c[i];
if(cur>=MAGIC){
g[id(i,j)].push_back(edge(id(i,j),id(i,MAGIC),d[i]));
}
else{
g[id(i,j)].push_back(edge(id(i,j),id(i,cur),d[i]));
}
}
}
fillbig(dist);
dist[id(1,min(s,MAGIC))]=0;
q.push({0,id(1,min(s,MAGIC))});
while(!q.empty()){
pii p=q.top();q.pop();
int sum=p.fi,x=p.se;
if(sum>dist[x]) continue;
foreach(it,g[x]){
int y=it->v,z=it->w;
if(dist[y]>dist[x]+z){
dist[y]=dist[x]+z;
q.push({dist[y],y});
}
}
}
fz(i,2,n){
int mn=0x3f3f3f3f3f3f3f3fll;
fz(j,0,MAGIC) mn=min(mn,dist[id(i,j)]);
cout<<mn<<endl;
}
return 0;
}
Atcoder Beginner Contest 164 E Two Currencies(拆点+最短路)的更多相关文章
- AtCoder Beginner Contest 164
比赛链接:https://atcoder.jp/contests/abc164 A - Sheep and Wolves #include <bits/stdc++.h> using na ...
- AtCoder Beginner Contest 100 2018/06/16
A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...
- AtCoder Beginner Contest 052
没看到Beginner,然后就做啊做,发现A,B太简单了...然后想想做完算了..没想到C卡了一下,然后还是做出来了.D的话瞎想了一下,然后感觉也没问题.假装all kill.2333 AtCoder ...
- AtCoder Beginner Contest 053 ABCD题
A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...
- AtCoder Beginner Contest 136
AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...
- AtCoder Beginner Contest 137 F
AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...
- AtCoder Beginner Contest 076
A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...
- AtCoder Beginner Contest 079 D - Wall【Warshall Floyd algorithm】
AtCoder Beginner Contest 079 D - Wall Warshall Floyd 最短路....先枚举 k #include<iostream> #include& ...
- AtCoder Beginner Contest 064 D - Insertion
AtCoder Beginner Contest 064 D - Insertion Problem Statement You are given a string S of length N co ...
随机推荐
- 初学Python-day12 装饰器函数
装饰器 1.概念 本质就是一个Python函数,其他函数在本身不变的情况下去增加额外的功能,装饰器的返回值是一个函数. 常用的场景:插入日志,事务处理,缓存,权限校验等. 2.普通函数回顾 1 def ...
- 如何将jdk12的源码导入idea
如何将jdk12的源码导入idea中 一 首先,在idea中新建一个java工程 接着,在本地找到jdk所在的文件目录,进入jdk目录,找到javasrc目录或者一个src.zip的压缩包, 在向下或 ...
- 【c++ Prime 学习笔记】第6章 函数
6.1 函数基础 函数定义包括:返回类型.函数名字.由0个或多个形参组成的列表以及函数体 通过调用运算符()来执行函数,它作用于一个表达式,该表达式是函数或函数指针.圆括号内是一个逗号隔开的实参列表, ...
- Java:Object对象小记
Java:Object对象小记 对 Java 中的 Object 对象,做一个微不足道的小小小小记 Object 的常用方法有哪些 clone() 方法:用于创建并返回当前对象的一份拷贝: 在Java ...
- [软工顶级理解组] Beta阶段测试报告
在测试过程中发现了多少Bug? 测试阶段发现并已修复的bug: 尚且存在,但是难以解决或者不影响使用的bug: 计算重修课程的时候,如果重修课程的课程号和原课程号不同,则GPA计算会出现误差.但我们无 ...
- Prometheus监控Canal
Prometheus监控Canal 一.背景 二.实现步骤 1.修改prometheus.yml配置文件 2.启动prometheus 3.查看prometheus是否成功接入canal 4.cana ...
- 架构师之路-https底层原理
引子 先说说我对架构师的理解.从业务能力上,需要的是发现问题和解决问题的能力:从团队建设上,需要的是能培养团队的业务能力:从项目管理上,把控好整个项目和软件产品的全生命周期. 我搜索了一下架构师的培训 ...
- C#写TXT文档
//C#写TXT文档 String strDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAs ...
- js点击事件 登录
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- docker 加入域名
先运行docker镜像 # 进入 docker 容器 mynginx 是容器名 docker exec -i -t mynginx /bin/bash #安装vim apt-get install v ...