孤岛营救与汽车加油行驶问题
题目链接:https://www.luogu.org/problemnew/show/P4011 (孤岛营救)|| https://www.luogu.org/problemnew/show/P4009 (汽车加油行驶)
题解:
两道分层图,所以我放在一起了=-=
别人都是对状态直接bfs了,我是对每个状态编号、建图,然后跑spfa。(感觉直接bfs好像会快一点,找时间学习一波qwq)
关于编号的注意事项就是不同点的编号一定不能重复,不然就会出现各种奇奇怪怪的错误。(血的教训啊...)
孤岛营救:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<bitset> 6 #define LL long long 7 #define RI register int 8 using namespace std; 9 const int INF = 0x7ffffff ; 10 const int N = 10 + 2 ; 11 const int CC = 100 + 10 ; 12 const int M = 1e6 + 10 ; 13 const int NN = 1e6 + 10 ; 14 15 const int cx[] = {-1,0,0,1} ; 16 const int cy[] = {0,1,-1,0} ; 17 18 inline int read() { 19 int k = 0 , f = 1 ; char c = getchar() ; 20 for( ; !isdigit(c) ; c = getchar()) 21 if(c == '-') f = -1 ; 22 for( ; isdigit(c) ; c = getchar()) 23 k = k*10 + c-'0' ; 24 return k*f ; 25 } 26 struct Edge { 27 int to, next, val ; 28 }e[M] ; 29 int n, m, p, k, t ; int head[NN], dis[NN] ; 30 int noo[N][N][N][N] ; // 11表示墙,其他数字表示钥匙 31 inline void add_edge(int x,int y,int vv) { 32 static int cnt = 1 ; 33 e[++cnt].to = y, e[cnt].next = head[x], head[x] = cnt, e[cnt].val = vv ; 34 } 35 36 inline void spfa() { 37 for(int i=1;i<=NN;i++) dis[i] = INF ; int s = 1 ; 38 deque<int>q ; q.push_back(s) ; dis[s] = 0 ; bitset<NN>inq ; 39 while(!q.empty()) { 40 int x = q.front() ; q.pop_front() ; 41 for(int i=head[x];i;i=e[i].next) { 42 int y = e[i].to ; 43 if(dis[y] > dis[x]+e[i].val) { 44 dis[y] = dis[x]+e[i].val ; 45 if(!inq[y]) { 46 if(!q.empty() && dis[y] < dis[q.front()]) q.push_front(y) ; 47 else q.push_back(y) ; 48 inq[y] = 1 ; 49 } 50 } 51 } 52 inq[x] = 0 ; 53 } 54 if(dis[t] == INF) printf("-1") ; 55 else printf("%d",dis[t]) ; 56 } 57 58 int main() { 59 n = read(), m = read(), p = read(), k = read() ; t = NN-10 ; 60 int x1, y1, x2, y2, ii ; 61 for(int i=1;i<=k;i++) { 62 x1 = read(), y1 = read(), x2 = read(), y2 = read(), ii = read() ; 63 if(!ii) { 64 noo[x1][y1][x2][y2] = noo[x2][y2][x1][y1] = 11 ; 65 } else noo[x1][y1][x2][y2] = noo[x2][y2][x1][y1] = ii ; 66 } 67 for(int s=0;s<(1<<p);s++) { 68 for(int i=1;i<=n;i++) { 69 for(int j=1;j<=m;j++) { 70 int p = s*CC + (i-1)*m + j ; 71 for(int k=0;k<4;k++) { 72 int xx = i+cx[k], yy = j+cy[k] ; 73 if(!xx || !yy || xx > n || yy > m) continue ; 74 int pp = s*CC + (xx-1)*m + yy ; 75 if( !noo[i][j][xx][yy] || (s&(1<<(noo[i][j][xx][yy]-1))) ) 76 add_edge(p,pp,1), add_edge(pp,p,1) ; 77 } 78 } 79 } 80 } 81 int nn = read() ; 82 for(int i=1;i<=nn;i++) { 83 int x = read(), y = read(), kk = read() ; 84 for(int s=0;s<(1<<p);s++) { 85 if(!(s&(1<<(kk-1)))) { // 没有该钥匙的状态可以转移到有该钥匙的状态 86 int p1 = s*CC + (x-1)*m + y, p2 = (s^(1<<(kk-1)))*CC + (x-1)*m + y ; 87 add_edge(p1,p2,0) ; 88 } 89 } 90 } 91 for(int s=0;s<(1<<p);s++) add_edge(s*CC+n*m,t,0) ; 92 spfa() ; 93 return 0 ; 94 }
汽车加油行驶:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<bitset> 6 #define LL long long 7 #define RI register int 8 using namespace std; 9 const int INF = 0x7ffffff ; 10 const int CC = 1e4 + 100 ; 11 const int N = 100 + 10 ; 12 const int NN = 1e6 + 10 ; 13 const int M = 1e6 + 10 ; 14 15 const int cx1[] = {-1,0} ; 16 const int cy1[] = {0,-1} ; 17 const int cx2[] = {1,0} ; 18 const int cy2[] = {0,1} ; 19 20 inline int read() { 21 int k = 0 , f = 1 ; char c = getchar() ; 22 for( ; !isdigit(c) ; c = getchar()) 23 if(c == '-') f = -1 ; 24 for( ; isdigit(c) ; c = getchar()) 25 k = k*10 + c-'0' ; 26 return k*f ; 27 } 28 struct Edge { 29 int to, next, val ; 30 }e[M] ; 31 int n, k, a, b, c, s, t ; int head[NN], dis[NN] ; 32 bool hh[N][N] ; 33 inline void add_edge(int x,int y,int vv) { 34 static int cnt = 0 ; 35 e[++cnt].to = y, e[cnt].next = head[x], head[x] = cnt, e[cnt].val = vv ; 36 } 37 38 inline void spfa() { 39 for(int i=1;i<=NN;i++) dis[i] = INF ; 40 deque<int>q ; q.push_back(s) ; dis[s] = 0 ; bitset<NN>inq ; inq[s] = 1 ; 41 while(!q.empty()) { 42 int x = q.front() ; q.pop_front() ; 43 for(int i=head[x];i;i=e[i].next) { 44 int y = e[i].to ; 45 if(dis[y] > dis[x]+e[i].val) { 46 dis[y] = dis[x]+e[i].val ; 47 if(!inq[y]) { 48 inq[y] = 1 ; 49 if(!q.empty() && dis[y] < dis[q.front()]) q.push_front(y) ; 50 else q.push_back(y) ; 51 } 52 } 53 } 54 inq[x] = 0 ; 55 } 56 printf("%d",dis[t]) ; 57 } 58 59 int main() { 60 // freopen("trav.in","r",stdin) ; 61 // freopen("trav.out","w",stdout) ; 62 n = read(), k = read(), a = read(), b = read(), c = read() ; t = (k+1)*CC + 10 ; 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=n;j++) hh[i][j] = read() ; 65 for(int now=k;now;now--) { 66 for(int i=1;i<=n;i++) { 67 for(int j=1;j<=n;j++) { 68 if(!hh[i][j]) { // 无加油站 69 for(int kk=0;kk<2;kk++) { 70 int xx = i+cx1[kk], yy = j+cy1[kk] ; 71 if(!xx || !yy || xx > n || yy > n) continue ; 72 add_edge(now*CC+(i-1)*n+j,(now-1)*CC+(xx-1)*n+yy,b) ; 73 } 74 for(int kk=0;kk<2;kk++) { 75 int xx = i+cx2[kk], yy = j+cy2[kk] ; 76 if(!xx || !yy || xx > n || yy > n) continue ; 77 add_edge(now*CC+(i-1)*n+j,(now-1)*CC+(xx-1)*n+yy,0) ; 78 } 79 } else { // 有加油站 80 for(int kk=0;kk<2;kk++) { 81 int xx = i+cx1[kk], yy = j+cy1[kk] ; 82 if(!xx || !yy || xx > n || yy > n) continue ; 83 add_edge(now*CC+(i-1)*n+j,(k-1)*CC+(xx-1)*n+yy,b+a) ; 84 } 85 for(int kk=0;kk<2;kk++) { 86 int xx = i+cx2[kk], yy = j+cy2[kk] ; 87 if(!xx || !yy || xx > n || yy > n) continue ; 88 add_edge(now*CC+(i-1)*n+j,(k-1)*CC+(xx-1)*n+yy,a) ; 89 } 90 } 91 // 创造加油站 =-= 92 for(int kk=0;kk<2;kk++) { 93 int xx = i+cx1[kk], yy = j+cy1[kk] ; 94 if(!xx || !yy || xx > n || yy > n) continue ; 95 add_edge(now*CC+(i-1)*n+j,(k-1)*CC+(xx-1)*n+yy,a+b+c) ; 96 } 97 for(int kk=0;kk<2;kk++) { 98 int xx = i+cx2[kk], yy = j+cy2[kk] ; 99 if(!xx || !yy || xx > n || yy > n) continue ; 100 add_edge(now*CC+(i-1)*n+j,(k-1)*CC+(xx-1)*n+yy,a+c) ; 101 } 102 } 103 } 104 } 105 for(int i=1;i<=n;i++) 106 for(int j=1;j<=n;j++) { 107 if(!hh[i][j]) { 108 for(int kk=0;kk<2;kk++) { 109 int xx = i+cx1[kk], yy = j+cy1[kk] ; 110 if(!xx || !yy || xx > n || yy > n) continue ; 111 add_edge(n*(i-1)+j,(k-1)*CC+(xx-1)*n+yy,c+b+a) ; 112 } 113 for(int kk=0;kk<2;kk++) { 114 int xx = i+cx2[kk], yy = j+cy2[kk] ; 115 if(!xx || !yy || xx > n || yy > n) continue ; 116 add_edge(n*(i-1)+j,(k-1)*CC+(xx-1)*n+yy,c+a) ; 117 } 118 } else { 119 for(int kk=0;kk<2;kk++) { 120 int xx = i+cx1[kk], yy = j+cy1[kk] ; 121 if(!xx || !yy || xx > n || yy > n) continue ; 122 add_edge(n*(i-1)+j,(k-1)*CC+(xx-1)*n+yy,b+a) ; 123 } 124 for(int kk=0;kk<2;kk++) { 125 int xx = i+cx2[kk], yy = j+cy2[kk] ; 126 if(!xx || !yy || xx > n || yy > n) continue ; 127 add_edge(n*(i-1)+j,(k-1)*CC+(xx-1)*n+yy,a) ; 128 } 129 } 130 } 131 for(int now=k;now>=0;now--) add_edge(now*CC+n*n,t,0) ; s = k*CC + 1 ; 132 spfa() ; 133 return 0 ; 134 }
转载于:https://www.cnblogs.com/zub23333/p/8697201.html
孤岛营救与汽车加油行驶问题相关推荐
- Loj#6223 Luogu P4009 汽车加油行驶 分层图最短路
这是本蒟蒻博客的第一篇文章,不规范之处敬请各位大佬指正和谅解orz Loj#6223+Luogu P4009 文章目录 前言 一.建模 二.代码实现 1.节点在图中的编号(分层图的存储) 2.建边 对 ...
- 【线性规划与网络流24题】汽车加油行驶问题 分层图
汽车加油行驶问题 Time Limit: 1 Sec Memory Limit: 128 MB Description 给定一个 N*N的方形网格,设其左上角为起点◎,坐标为( 1,1),X轴向右为 ...
- 洛谷 - P4009 汽车加油行驶问题(分层图最短路/最小费用最大流)
题目链接:点击查看 题目大意:给出一个n*n的矩阵表示道路,途中有一些加油站,现在要从点(1,1)到达点(n,n),问最小花费,其中的一些规则如下: 汽车只能沿着网格边行驶,装满油后可以行驶K条边,出 ...
- [codevs 1912] 汽车加油行驶问题
http://codevs.cn/problem/1912/ 题解: 看到题后第一反应就是费用流,因为求的就是最小费用,还要加入邮箱中剩余油量为参数,因为剩余油量不同到达那个结点后所要执行的操作也不同 ...
- P4009 汽车加油行驶问题
题目描述: 题解: 看了很多题解,无论什么解法都绕不开分层图 在本题中加满油的车每次可以移动K步,那么我们就可以建立一个K+1层的分层图,表示汽车油量k的状态(油量0-k),然后根据题目要求建图 首先 ...
- 洛谷 P4009 汽车加油行驶问题 题解
原题题面 网络流24题?费用流?不存在的 tag都是骗人的 首先看题,仔细想想,这不就是一个最短路吗? 然而本蒟蒻看不出一些题解中说的分层图最短路,于是直接写单源最短路 从 (1,1) 往 (n,n) ...
- [codevs 1911] 孤岛营救问题
http://codevs.cn/problem/1911/ 题解: 这个题简单的做法就是建立分层图,还记得那篇 汽车加油行驶问题 吗?那是按照邮箱剩余油量建立分层图,而这个题要以获取钥匙的状态建立分 ...
- 算法设计与分析——贪心算法——汽车加油问题
汽车加油问题:一辆汽车加满油后可行驶n公里,旅途中有若干个加油站,两加油站间距离不超n 公里,起点离第一个加油站距离及最后一个加油站离终点距离也不超过n公里.算法给出应在哪些加油站停靠加油,使沿途加油 ...
- 贪心----汽车加油问题
汽车加油问题 Time Limit: 1000 ms Memory Limit: 65536 KiB`` Problem Description 一辆汽车加满油后可行驶n公里.旅途中有若干个加油站.设 ...
最新文章
- MEF: MSDN 杂志上的文章(9) 控制部件创建策略 ???
- python科学计数法转换_柳小白Python学习笔记35 Excel之科学计数法类型转换及数据选取1...
- 2021-03-04 Halcon初学者知识 【18】谈谈秩滤波(Rank filter)
- 万事俱备只缺你,6月亚洲消费电子展不见不散
- css3 :nth-child()选择器的使用
- 如何关闭Windows10任务栏里的应用图标
- docker删除镜像和删除容器
- java 上下文加载器_【深入理解Java虚拟机 】线程的上下文类加载器
- Protobuf介绍及简单使用(下)之文件读写
- LLVM编译器基础 架构
- html5 删除llocalstorage变量,删除存储在浏览器中的 Local Storage 数据《 HTML5:Web 存储 》...
- 实习踩坑之路:JSON格式错误,导致Java异常JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out o
- Adobe Flash Player不是最新版本,导致视频无法播放?
- Oracle函数之ratio_to_report函数
- 浏览器打开苏宁易购证书错误
- rar压缩包已加密如何解除,rar压缩包权限限制怎么办?
- Nature Communications:使用连接组的嵌入向量表征映射大脑结构与功能之间的高阶关系
- 每日积累【Day 3】Hbase架构深入学习
- 基于最大熵Maxent-ArcGis地理分布预测教程
- 浏览器javascript书签小应用
热门文章
- 全球及中国蔬菜泥配料行业竞争策略及投资潜力研究报告2021-2027年版
- 对话国际农民丰收节贸易会-林育庆:菲律宾谋定中国农业
- 发展农业对话国际农民丰收节贸易会 菲律宾学中国还是印度?
- 咸宁书写桂花产业-国情研究·万祥军:特色农业谋定大健康
- web自动化测试—selenium游览器下拉框操作
- MySql中的运算符
- 成员变量和属性区别(@property那点事儿)
- 【洛谷P2927 [USACO08DEC]拼图游戏Jigsaw Puzzles】深搜
- USACO 2.3 Money Systems(DP)
- 委托、事件与Observer设计模式