[网络流24题] 深海机器人

[网络流24题] 深海机器人

时间限制:1 s   内存限制:128 MB

深海机器人问题
«问题描述:
深海资源考察探险队的潜艇将到达深海的海底进行科学考察。潜艇内有多个深海机器
人。潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动。深海机器人在移动中还
必须沿途采集海底生物标本。沿途生物标本由最先遇到它的深海机器人完成采集。每条预定
路径上的生物标本的价值是已知的,而且生物标本只能被采集一次。本题限定深海机器人只
能从其出发位置沿着向北或向东的方向移动,而且多个深海机器人可以在同一时间占据同一
位置。
«编程任务:
用一个P´Q 网格表示深海机器人的可移动位置。西南角的坐标为(0,0),东北角的坐

标为 (Q,P)。

给定每个深海机器人的出发位置和目标位置,以及每条网格边上生物标本的价值。计算
深海机器人的最优移动方案,使深海机器人到达目的地后,采集到的生物标本的总价值最高。
«数据输入:
由文件shinkai.in提供输入数据。文件的第1 行为深海机器人的出发位置数a,和目的地
数b,第2 行为P和Q 的值。接下来的P+1 行,每行有Q 个正整数,表示向东移动路径上
生物标本的价值,行数据依从南到北方向排列。再接下来的Q+1 行,每行有P 个正整数,
表示向北移动路径上生物标本的价值,行数据依从西到东方向排列。接下来的a行,每行有
3 个正整数k,x,y,表示有k个深海机器人从(x,y)位置坐标出发。再接下来的b行,每行有3
个正整数r,x,y,表示有r个深海机器人可选择(x,y)位置坐标作为目的地。
«结果输出:
程序运行结束时,将采集到的生物标本的最高总价值输出到文件shinkai.out中。
shinkai.in
1 1
2 2
1 2
3 4
5 6
7 2
8 10
9 3
2 0 0

2 2 2

shinkai.out

42

1<=P,Q<=15 1<=a,b<=10

主要的难点是如何通过一个点却只计算一次价值,事实上处理方法很简单,连两次边,第一条权值为0,流量inf,第二次权值为x,流量为1。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=300;
 4 const int maxm=maxn*8;
 5 const int inf=0x3fffffff;
 6 int a,b,p,q,num[17][17],cnt;
 7 int tot=-1,fi[maxn],next[maxm],to[maxm],cost[maxm],flow[maxm];
 8 int ans,s,t,dis[maxn],que[maxn],head,tail,cur[maxn],vis[maxn];
 9 void edge_add(int x,int y,int f,int c){
10     to[++tot]=y;next[tot]=fi[x];fi[x]=tot;cost[tot]=c;flow[tot]=f;
11     to[++tot]=x;next[tot]=fi[y];fi[y]=tot;cost[tot]=-c;flow[tot]=0;
12 }
13 bool bfs(){
14     head=tail=1;
15     for(int i=s;i<=t;i++)cur[i]=fi[i],vis[i]=0,dis[i]=-inf;
16     que[++tail]=s;vis[s]=1;dis[s]=0;
17     while(head!=tail){
18         head++;
19         if(head==290)head=1;
20         int u=que[head];
21         vis[u]=0;
22         for(int i=fi[u];i+1;i=next[i]){
23             if(flow[i]&&dis[to[i]]<dis[u]+cost[i]){
24                 dis[to[i]]=dis[u]+cost[i];
25                 if(!vis[to[i]]){
26                     vis[to[i]]=1;
27                     tail++;
28                     if(tail==290)tail=1;
29                     que[tail]=to[i];
30                 }
31             }
32         }
33     }
34     return dis[t]!=-inf;
35 }
36 int dfs(int x,int f){
37     vis[x]=1;
38     if(x==t)return f;
39     for(int i=cur[x];i+1;i=next[i]){
40         cur[x]=i;
41         if(!vis[to[i]]&&flow[i]&&dis[to[i]]==dis[x]+cost[i]){
42             int g=dfs(to[i],min(flow[i],f));
43             if(g){
44                 ans+=cost[i]*g;
45                 flow[i]-=g;
46                 flow[i^1]+=g;
47                 return g;
48             }
49         }
50     }
51     return 0;
52 }
53 void dinic(){
54     while(bfs())
55         while(dfs(s,inf));
56     printf("%d\n",ans);
57 }
58 int main()
59 {
60     scanf("%d%d",&a,&b);
61     scanf("%d%d",&p,&q);
62     memset(fi,-1,sizeof(fi));
63     p++;q++;
64     for(int i=1;i<=p;i++)
65         for(int j=1;j<=q;j++)
66             num[i][j]=++cnt;
67     s=0;t=cnt+1;
68     for(int i=1;i<=p;i++){
69         for(int j=1;j<q;j++){
70             int x;
71             scanf("%d",&x);
72             edge_add(num[i][j],num[i][j+1],inf,0);
73             edge_add(num[i][j],num[i][j+1],1,x);
74         }
75     }
76     for(int i=1;i<=q;i++){
77         for(int j=1;j<p;j++){
78             int x;
79             scanf("%d",&x);
80             edge_add(num[j][i],num[j+1][i],inf,0);
81             edge_add(num[j][i],num[j+1][i],1,x);
82         }
83     }
84     for(int i=1;i<=a;i++){
85         int k,x,y;
86         scanf("%d%d%d",&k,&x,&y);
87         edge_add(s,num[x+1][y+1],k,0);
88     }
89     for(int i=1;i<=b;i++){
90         int k,x,y;
91         scanf("%d%d%d",&k,&x,&y);
92         edge_add(num[x+1][y+1],t,k,0);
93     }
94     dinic();
95     return 0;
96 }

原文地址:https://www.cnblogs.com/Turkeyghb/p/8178759.html

时间: 2024-10-31 11:38:34

[网络流24题] 深海机器人的相关文章

「网络流24题」 题目列表

「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分图最小路径覆盖 <3> 4 魔术球问题 <4> 5 圆桌问题 <5> 6 最长递增子序列问题 <6> 7 试题库问题 <7> 8 机器人路径规划问题 <8> 9 方格取数问题 二分图最大点权独立集 <9> 10 餐巾计划问题

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

【网络流24题----14】孤岛营救问题

孤岛营救问题 Time Limit: 1 Sec  Memory Limit: 128 MB Description 1944年,特种兵麦克接到国防部的命令.要求马上赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图.迷宫的外形是一个长方形,其南北方向被划分为 N行,东西方向被划分为 M列,于是整个迷宫被划分为 N×M个单元.每个单元的位置可用一个有序数对 (单元的行号,单元的列号)来表示.南北或东西方向相邻的 2个单元之间可能互

【网络流24题】

网络流 网络流24题 [最小路径覆盖问题] 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没入度的右侧点开始把整条路径输出来即可. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=100000,inf=0x3f3f3f3f; int n,m,

【网络流24题】魔术球问题

P1226 - [网络流24题]魔术球问题 Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.例如,在4 根柱子上最多可 放11个球. ′编程任务: 对于给定的n,计算在 n根柱子上最多能放多少个球. Input 第1 行有 1个正整数n,表示柱子数. Output 第一行是球

AC日记——[网络流24题]骑士共存 cogs 746

746. [网络流24题] 骑士共存 ★★☆   输入文件:knight.in   输出文件:knight.out   简单对比时间限制:1 s   内存限制:128 MB 骑士共存问题 «问题描述: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘 上某些方格设置了障碍,骑士不得进入. «编程任务: 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击. «数据输入: 由文件knight.in给出输入数据.第一行

网络流24题

刷刷基础题来巩固一下基础.. #1.飞行员配对方案问题 pdf链接 听说各大OJ的题面都和pdf不同.. 嗯连边匹配就行.. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> using namespace std; const int Maxn = 110; struct node { int y, next

739. [网络流24题] 运输问题

739. [网络流24题] 运输问题 ★★   输入文件:tran.in   输出文件:tran.out   简单对比时间限制:1 s   内存限制:128 MB «问题描述:«编程任务:对于给定的m 个仓库和n 个零售商店间运送货物的费用,计算最优运输方案和最差运输方案.«数据输入:«结果输出:程序运行结束时,将计算出的最少运输费用和最多运输费用输出到文件tran.out中.输入文件示例 输出文件示例tran.in2 3220 280170 120 21077 39 105 150 186 1

【网络流24题】 No.12 软件补丁问题(最小转移代价 最短路)

[题意] T 公司发现其研制的一个软件中有 n 个错误, 随即为该软件发放了一批共 m 个补丁程序. 每一个补丁程序都有其特定的适用环境, 某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才可以使用.一个补丁在排除某些错误的同时, 往往会加入另一些错误.换句话说, 对于每一个补丁 i, 都有 2 个与之相应的错误集合 B1[i]和 B2[i],使得仅当软件包含 B1[i]中的所有错误, 而不包含 B2[i]中的任何错误时, 才可以使用补丁 i. 补丁 i 将修复软件中的某些错误 F1[