题目链接

思路

把每个点拆成\(5\)个点\(id(x,y),id(x,y)+n,id(x,y)+2*n,id(x,y)+3*n,id(x,y)+4*n\),分别表示到这个点时的方向为上,右,下,左和静止点

非静止点的决策如下:

1.走到对应的同方向的非静止点,代价为\(w\)

2.走到对应的同方向的静止点,代价为\(2w\)

静止点的决策如下:

1.走到四联通的对应方向的非静止点,代价为\(2w\)

2.走到四联通的静止点,代价为\(2w\)

直接建图跑最短路就行了,源点为\((r1,c1)\)对应的静止点,汇点为\((r2,c2)\)对应的静止点

代码:

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <map>
#include <set> using namespace std; #define ull unsigned long long
#define pii pair<int, int>
#define uint unsigned int
#define mii map<int, int>
#define lbd lower_bound
#define ubd upper_bound
#define INF 0x3f3f3f3f
#define IINF 0x3f3f3f3f3f3f3f3fLL
#define DEF 0x8f8f8f8f
#define DDEF 0x8f8f8f8f8f8f8f8fLL
#define vi vector<int>
#define ll long long
#define mp make_pair
#define pb push_back
#define re register
#define il inline #define N 50010
const int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1}; struct Edge {
int next, to, w;
}e[5000000]; int R, C, r1, c1, r2, c2, n, S, T;
int head[N+5], eid;
int d[N+5], pre[N+5];
int W[105][105][4];
bool inq[N+5]; void addEdge(int u, int v, int w) {
e[++eid].next = head[u];
e[eid].to = v;
e[eid].w = w;
head[u] = eid;
} int id(int x, int y) {
return (x-1)*C+y;
} void add(int x, int y) {
for(int t = 0; t < 4; ++t) {
int nx = x+dir[t][0], ny = y+dir[t][1];
if(nx < 1 || nx > R || ny < 1 || ny > C) continue;
int w = W[x][y][t];
if(!w) continue;
addEdge(id(x, y)+t*n, id(nx, ny)+t*n, w);
addEdge(id(x, y)+t*n, id(nx, ny)+4*n, 2*w);
addEdge(id(x, y)+4*n, id(nx, ny)+t*n, 2*w);
addEdge(id(x, y)+4*n, id(nx, ny)+4*n, 2*w);
}
} void spfa() {
memset(d, 0x3f, sizeof d);
d[S] = 0;
static queue<int> q;
q.push(S);
pre[S] = 0;
inq[S] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
inq[u] = 0;
for(int i = head[u]; i; i = e[i].next) {
int v = e[i].to, w = e[i].w;
if(d[v] > d[u]+w) {
d[v] = d[u]+w;
pre[v] = u;
if(!inq[v]) inq[v] = 1, q.push(v);
}
}
}
} void clear() {
memset(head, 0, sizeof head);
memset(W, 0, sizeof W);
eid = 0;
} int main() {
int kase = 0;
while(~scanf("%d%d%d%d%d%d", &R, &C, &r1, &c1, &r2, &c2) && R && C && r1 && c1 && r2 && c2) {
n = R*C;
clear();
for(int i = 1, t; i < R; ++i) {
for(int j = 1; j < C; ++j) {
scanf("%d", &t);
W[i][j][1] = W[i][j+1][3] = t;
}
for(int j = 1; j <= C; ++j) {
scanf("%d", &t);
W[i][j][2] = W[i+1][j][0] = t;
}
}
for(int j = 1, t; j < C; ++j) {
scanf("%d", &t);
W[R][j][1] = W[R][j+1][3] = t;
}
for(int i = 1; i <= R; ++i)
for(int j = 1; j <= C; ++j) add(i, j);
S = id(r1, c1)+4*n, T = id(r2, c2)+4*n;
spfa();
printf("Case %d: ", ++kase);
if(d[T] == INF) printf("Impossible\n");
else printf("%d\n", d[T]);
}
return 0;
}

UVa1078 Steam Roller——拆点+最短路的更多相关文章

  1. UVaLive 4128 Steam Roller (多决策最短路)

    题意:给定一个图,r 根横线, c 根竖线.告诉你起点和终点,然后从起点走,每条边有权值,如果是0,就表示无法通行.走的规则是:如果你在下个路要转弯,会使这段路的时间加倍,但是如果一条路同时是这样,那 ...

  2. 【NOIP2017】逛公园 拆点最短路+拓扑(记忆化搜索

    题目描述 策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策 ...

  3. UVALive 4128 Steam Roller(最短路(拆点,多状态))

    题意:模拟了汽车的行驶过程,边上的权值为全速通过所消耗的时间,而起步(从起点出发的边).刹车(到终点结束的边).减速(即将拐弯的边).加速(刚完成拐弯的边)这四种不能达到全速的情况,消耗的时间为权值* ...

  4. UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。

    题意: 给一个由n*m个正方形格子组成的矩形,其中每个格子的边都是可以走的,长度给定,规定:如果在进入该路前需要拐弯,或者走完该路需要拐弯,都是需要付出双倍距离的(每条路最多算2倍).问从起点到终点的 ...

  5. hdu4725 拆点+最短路

    题意:有 n 个点,每个点有它所在的层数,最多有 n 层,相邻两层之间的点可以互相到达,消耗 c (但同一层并不能直接到达),然后还有一些额外的路径,可以在两点间互相到达,并且消耗一定费用.问 1 点 ...

  6. Atcoder Beginner Contest 164 E Two Currencies(拆点+最短路)

    题目链接 题意:有 \(n\) 个城市,它们由 \(m\) 条双向道路连接,保证它们能够彼此到达.第 \(i\) 条道路连接 \(u_i,v_i\),需要花费 \(x_i\) 个银币,耗费 \(t_i ...

  7. Shortest Path Codeforces - 59E || 洛谷P1811 最短路_NOI导刊2011提高(01)

    https://codeforces.com/contest/59/problem/E 原来以为不会..看了题解发现貌似自己其实是会的? 就是拆点最短路..拆成n^2个点,每个点用(i,j)表示,表示 ...

  8. XJOI网上同步训练DAY6 T1

    思路:考试的时候直接想出来了,又有点担心复杂度,不过还是打了,居然是直接A掉,开心啊. 我们发现,Ai<=7,这一定是很重要的条件,我们考虑状态压缩,去枚举路径中出现了哪些数字,然后我们把原来n ...

  9. AtCoder Regular Contest

    一句话题解 因为上篇AGC的写的有点长……估计这篇也短不了所以放个一句话题解方便查阅啥的吧QwQ 具体的题意代码题解还是往下翻…… ARC 058 D:简单容斥计数. E:用二进制表示放的数字,然后状 ...

随机推荐

  1. vue 解决jsonp跨域

    在Vue中使用jsonp 参考链接:https://blog.csdn.net/m0_38134431/article/details/87930647 在vue中使用vue-jsonp 参考链接:h ...

  2. Guava源码阅读-base-CharMatcher

    package com.google.common.base; (部分内容摘自:http://blog.csdn.net/idealemail/article/details/53860439) 之前 ...

  3. 牛客小白月赛16 H 小阳的贝壳 (差分+线段树)

    链接:https://ac.nowcoder.com/acm/contest/949/H来源:牛客网 题目描述 小阳手中一共有 n 个贝壳,每个贝壳都有颜色,且初始第 i 个贝壳的颜色为 colico ...

  4. Java基础部分 2

    一. Java基础部分 2 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 2 2.Java有没有goto? 2 3.说说&和&&am ...

  5. Lucene 全文检索

    基于 lucene 8 1 Lucene简介 Lucene是apache下的一个开源的全文检索引擎工具包. 1.1 全文检索(Full-text Search) 全文检索就是先分词创建索引,再执行搜索 ...

  6. gitlab LFS 的应用实践

    今天看到的gitlab LFS的文档,将自己的理解整理成博客,加深自己的印象.具体gitlab LFS的介绍可以直接百度了,不在这里详细阐述.只提一下他的作用:LFS就是Large File Stor ...

  7. LeetCode 答案(python)1-17

    1.给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], targe ...

  8. Devexpress xaf针对某个用户登录后在面板中设置导航无效的解决方法

    Devexpress xaf框架生成的项目默认情况下导航栏是显示在左侧,有时候我们用某个账户登录后,发现导航栏无法显示在左侧,操作十分不方便.我们可以去数据库删除当前登录用户的自定义布局 解决方法如下 ...

  9. IntelliJ IDEA热部署插件JRebel免费激活图文教程(持续更新)转载

    之前教了大家如何免费激活IDEA,大家学会了吗?今天再来教大家如何免费激活JRebel插件,实现真正的热部署,无论是改了代码片段还是配置文件,都可以做到不用重新启动就生效,这种酸爽,谁用谁知道! 这次 ...

  10. MySql 8.0.11 客户端连接失败:2059 - Authentication plugin 'caching_sha2_password' cannot be loaded: ....

    近期,换了新笔记本,重新安装了MySql数据库和客户端工具Navicat Premium 12.我是从官网上下载的MySql数据库,版本为8.0.11,链接:https://dev.mysql.com ...