[JOI 2017 Final] 足球 (建图,最短路)
题面
题解
我们可以总结出球的两种状态,要么自己飞,要么在球员脚下被带飞。
自己飞的情况下,他只能单向直线运动,每一步代价为A,被带飞可以乱走,每一步代价为C。
从自己飞到被带飞需要一个距离自己最近的球员过来,代价为 ,对于每个格点,这个代价都是确定的,因为球不可能两次到同一个球员脚下,所以球员就相当于一次性的工具人,输入后bfs处理
就可以了。
从被带飞到自己飞需要踢一脚,给它自由,代价为B。
那么我们可以把每个格点拆成5个点,然后建个图。
自己飞要四个点,分别表示四个方向,每个点朝那个方向的下一个同类点连一条单向边,权值为A,这样就可以模拟出单向运动了。
被带飞就需要单独一个点,向四个方向的带飞点连双向边,权值为C,这样球就可以乱走了。
自己飞的四个点向被带飞的一个点分别连一条单向边,权值为 ,表示球员跑过来,把它带飞。
被带飞的一个点向自己飞的四个点分别连一条单向边,权值为 B,表示分别向四个方向踢一脚的情况。
这样就可以直接求最短路了。
不推荐用 Slow Path Finding Algorithm。
CODE
注意,实际行数列数是 ≤ 501 的,总共有 251001 个点,特别坑
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
#include<bitset>
#include<iostream>
#define MAXN 251010
#define LL long long
#define ULL unsigned LL
#define rg register
#define lowbit(x) (-(x) & (x))
#define ENDL putchar('\n')
#define DB double
#define bs bitset<105>
//#pragma GCC optimize(2)
//#pragma G++ optimize(3)
//#define int LL
using namespace std;
char char_read_before = 1;
inline int read() {
int f = 1,x = 0;char s = char_read_before;
while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 - '0' + s;s = getchar();}
char_read_before = s;return x * f;
}
template<typename T__>
inline T__ Abs(T__ x) {return x < 0 ? -x:x;}
int zxy; // 用来膜的
int n,m,i,j,s,o,k,h,w,N,S,T;
int x[MAXN],y[MAXN];
int dpp[505][505];
bool v[505][505];
int dx[4] = {0,0,-1,1};
int dy[4] = {-1,1,0,0};
struct itn{
int x,y,s;
itn(){x=y=s=0;}
itn(int X,int Y,int S){x=X;y=Y;s=S;}
};
queue<itn> b;
int L,R,U,D;
LL A,B,C;
struct it{
int v;
LL w;
it(){v=w=0;}
it(int V,LL W){v = V;w = W;}
};
vector<it> g[MAXN*5];
LL dp[MAXN*5] = {(LL)1e18};
bool f[MAXN*5];
inline int I(int x,int y) {return (x-1)*w + y;}
inline int bing(int a,int b) {return dp[a] < dp[b] ? a:b;}
int tre[MAXN*20],M;
inline void mt(int n){M=1;while(M < n+2) M <<= 1;}
inline void addt(int x,int y) {
int s = M+x;tre[s] = y;s >>= 1;
while(s) tre[s] = bing(tre[s<<1],tre[s<<1|1]),s >>= 1;
}
inline int allt() {return tre[1];}
void dij() {
mt(N*5);
dp[S] = 0;
addt(S,S);
for(int i = 1;i < N*5;i ++) {
int t = allt();
if(!t) break;
f[t] = 1;
for(int j = 0;j < g[t].size();j ++) {
if(!f[g[t][j].v]) {
dp[g[t][j].v] = min(dp[g[t][j].v],dp[t] + g[t][j].w);
addt(g[t][j].v,g[t][j].v);
}
}
addt(t,0);
}
}
signed main() {
h = read()+1;w = read()+1;
N = h*w;
A = read();B = read();C = read();
n = read();
for(int i = 1;i <= n;i ++) {
x[i] = read()+1;y[i] = read()+1;
dpp[x[i]][y[i]] = 0;
v[x[i]][y[i]] = 1;
b.push(itn(x[i],y[i],0));
}
while(!b.empty()) {
itn t = b.front();
b.pop();
for(int i = 0;i < 4;i ++) {
itn t1(t.x + dx[i],t.y + dy[i],t.s + 1);
if(t1.x < 1 || t1.y < 1 || t1.x > h || t1.y > w || v[t1.x][t1.y]) continue;
dpp[t1.x][t1.y] = t1.s;
v[t1.x][t1.y] = 1;
b.push(t1);
}
}
S = I(x[1],y[1])+4*N;
T = I(x[n],y[n])+4*N;
for(int i = 1;i <= h;i ++) {
for(int j = 1;j <= w;j ++) {
LL pd = dpp[i][j]*C;
int d1 = I(i,j),d2 = d1 + N,d3 = d2 + N,d4 = d3 + N,d5 = d4 + N;
dp[d1] = dp[d2] = dp[d3] = dp[d4] = dp[d5] = (LL)1e17;
if(i > 1) {
g[d1].push_back(it(I(i-1,j),A));
g[d5].push_back(it(I(i-1,j)+4*N,C));
}
if(i < h) {
g[d2].push_back(it(I(i+1,j)+N,A));
g[d5].push_back(it(I(i+1,j)+4*N,C));
}
if(j > 1) {
g[d3].push_back(it(I(i,j-1)+2*N,A));
g[d5].push_back(it(I(i,j-1)+4*N,C));
}
if(j < w) {
g[d4].push_back(it(I(i,j+1)+3*N,A));
g[d5].push_back(it(I(i,j+1)+4*N,C));
}
g[d1].push_back(it(d5,pd));
g[d2].push_back(it(d5,pd));
g[d3].push_back(it(d5,pd));
g[d4].push_back(it(d5,pd));
g[d5].push_back(it(d1,B));
g[d5].push_back(it(d2,B));
g[d5].push_back(it(d3,B));
g[d5].push_back(it(d4,B));
}
}
dij();
printf("%lld\n",dp[T]);
return 0;
}
[JOI 2017 Final] 足球 (建图,最短路)的更多相关文章
- 「JOI 2017 Final」JOIOI 王国
「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...
- 【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)
[题解]LOJ2759. 「JOI 2014 Final」飞天鼠(最短路) 考虑最终答案的构成,一定是由很多飞行+一些上升+一些下降构成. 由于在任何一个点上升或者下降代价是一样的,所以: 对于上升操 ...
- uva10067 Playing with Wheels 【建图+最短路】
题目:option=com_onlinejudge&Itemid=8&page=show_problem&problem=1008">uva10067 Play ...
- 【建图+最短路】Bzoj1001 狼抓兔子
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个 ...
- CodeForces 786B Legacy(线段树优化建图+最短路)
[题目链接] http://codeforces.com/problemset/problem/786/B [题目大意] 给出一些星球,现在有一些传送枪,可以从一个星球到另一个星球, 从一个星球到另一 ...
- 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- G. 神圣的 F2 连接着我们 线段树优化建图+最短路
这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...
- 【SDOI2017】天才黑客(前后缀优化建图 & 最短路)
Description 给定一张有向图,\(n\) 个点,\(m\) 条边.第 \(i\) 条边上有一个边权 \(c_i\),以及一个字符串 \(s_i\). 其中字符串 \(s_1, s_2, \c ...
- BZOJ 4289: PA2012 Tax 差分建图 最短路
https://www.lydsy.com/JudgeOnline/problem.php?id=4289 https://www.cnblogs.com/clrs97/p/5046933.html ...
随机推荐
- 关于string类型的大小写转换函数
对于string类型的有力工具 transform(s.begin(), s.end(), s.begin(),::tolower)大写转小写 transform(s.begin(), s.end() ...
- 使用.NetCore自带的后台作业,出入队简单模拟生产者消费者处理请求响应的数据
环境:Core:3.1的项目 说明:由于该方案为个人测试项目,重启时队列中的部分数据很可能会丢失, 对数据有要求的该方案不适用,不能照搬需要持久化处理, 另外发布到Linux Docker中通常不会自 ...
- 鼠标右键打开powershell
不需要更改配置文件什么的. 在桌面空白处按住Shift键同时鼠标右击,看看是不是就有了呢.
- NC16462 [NOIP2015]跳石头
NC16462 [NOIP2015]跳石头 题目 题目描述 一年一度的"跳石头"比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块 ...
- 各种Git Bash乱码解决
乱码情景一: 当使用git log 出现乱码时,修改 %GIT_HOME%\etc\gitconfig 文件,加入如下内容: [gui] encoding = utf-8[i18n] commiten ...
- java -jar -Xbootclasspath/a:/xxx/config xxx .jar 和 java -jar xxx .jar 的区别
1.如果有用Xbootclasspath的话则config的文件会直接覆盖jar里面的resouces文件,覆盖application.yml ,也会覆盖logback-spring.xml ,比如j ...
- zookeeper Caused by: java.lang.IllegalArgumentException: myid file is missing
zookeeper 安装集群,配置文件和data和其它都没有问题. 则需要在data里面下添加一个myid 文件 myid里面的数据个service一致 比如.cnf里面配置是 dataDir=/us ...
- raspberrypi系统在加入k8s作为node节点时遇到的问题
新买的树莓派4b到货后就迫不及待的烧录上raspberrypi系统,将新派加入我的k8s集群,期间遇到了点小挫折,好歹也一个一个解决了: 一.kubelet版本不对导致无法加入k8s集群 在执行kub ...
- 多表查询_练习1&练习2&练习3
准备表: -- 部门表 CREATE TABLE dept ( id INT PRIMARY KEY PRIMARY KEY, -- 部门id dname VARCHAR(50), -- 部门名称 l ...
- 整数分解和for循环
整数的分解: 一个整数是由多位数字组成的,那么如何能分解出整数的各个位上的数字呢 对一个整数做%10的操作,就可以得到它的个位数 对一个整数做/10的操作,就去掉了他的个位数 然后再对2的结果做%10 ...