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

Posted turkeyghb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[网络流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 }
View Code

 

以上是关于[网络流24题] 深海机器人的主要内容,如果未能解决你的问题,请参考以下文章

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

网络流24题之深海机器人问题

网络流24题(好大的坑啊)

网络流 24 题 解题报告

网络流 24 题 解题报告

洛谷P4012 深海机器人问题(费用流)