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 ...
随机推荐
- 用C++实现的数独解题程序 SudokuSolver 2.4 及实例分析
SudokuSolver 2.4 程序实现 本次版本实现了 用C++实现的数独解题程序 SudokuSolver 2.3 及实例分析 里发现的第三个不完全收缩 grp 算法 thirdGreenWor ...
- Git浅析
Git浅析 索引 Git的常用命令 GitHub的使用 Git版本创建和回退 Git的工作区和暂存区 Git分支管理 1-Git的常用命令 01.创建一个版本库--进入相应的目录 git init 可 ...
- nvidia-msi命令解读
nvidia-msi 或者 watch -n 1 nvidia-smi 打印出表格中: 第一栏的Fan:N/A是风扇转速,从0到100%之间变动,这个速度是计算机期望的风扇转速,实际情况下如果风扇堵转 ...
- valid-palindrome leetcode C++
Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...
- Luogu P2467 [SDOI2010]地精部落 | 神奇的dp
题目链接 DP 题目大意:给定一个数n,求1~n这n个整数的所有排列中有多少个波动数列,将这个数量%p后输出. 什么是波动数列呢?顾名思义,就是一个大.一个小.一个大.一个小--或者是一个小.一个大. ...
- IM服务器:开发一个高并发的IM服务器难在哪
IM服务器要实现的最基本功能就是消息的转发.--好像是一句废话! 这就意味着IM服务器要为每个登录用户创建一个与该用户信息相关的内存上下文,为方便描述我们在这里称之为:user_context.use ...
- UVA1104 Chips Challenge
一.题目 有一个 \(n\times n\) 的矩阵,每个元素可能是 ..C./ 的其中一种,分别表示可以放置芯片.已经放置了芯片.不能放置芯片,你可以分别决定是否可以放置芯片的位置放置芯片. 最后需 ...
- Dubbo的反序列化安全问题-Hessian2
0 前言 本篇是系列文章的第一篇,主要看看Dubbo使用反序列化协议Hessian2时,存在的安全问题.文章需要RPC.Dubbo.反序列化等前提知识点,推荐先阅读和体验Dubbo以及反序列化漏洞. ...
- Linux下安装、配置、启动与访问RabbitMQ
一.下载 首先第一步要下载三个rpm安装包,为了方便安装与学习,给出下载途径 网盘网址:https://pan.baidu.com/s/18Z64Lb9KQpRh10RzqZBdoQ 提取码:094v ...
- Git基本教程
git的发展 Git 两周开发 Linus开发,主要是为了管理大量人员维护代码 Git分布式版本控制系统 基本命令 history:查看之前用过的命令 vimtutor git配置 查看配置 git ...