列表

详情


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

描述

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

给定每个深海机器人的出发位置和目标位置,以及每条网格边上生物标本的价值。计算深海机器人的最优移动方案,使深海机器人到达目的地后,采集到的生物标本的总价值最高。

输入描述

第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)位置坐标作为目的地。

输出描述

程序运行结束时,将采集到的生物标本的最高总价值输出

示例1

输入:

1 1
2 2
1 2
3 4
5 6
7 2
8 10
9 3
2 0 0
2 2 2

输出:

42

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2022-11-09 22:39:19

#include<bits/stdc++.h>
using namespace std;

const int MAXN=305;
const int MAXM=1e5+5;
const int INF=1e8;
struct EDGE
{
    int to,nxt,flow,cost;
}edge[MAXM];
int head[MAXN],tot=1;
int pre[MAXN],incf[MAXN],dis[MAXN];
bool vis[MAXN];
int s,t,maxcost;
int a,b,n,m;
void add(int x,int y,int z,int c)
{
    edge[++tot]=(EDGE){y,head[x],z,c},head[x]=tot;
    edge[++tot]=(EDGE){x,head[y],0,-c},head[y]=tot;
}
bool spfa()
{
    queue<int>q;
    memset(dis,-0x3f,sizeof(dis));
    q.push(s),dis[s]=0,vis[s]=1,incf[s]=INF;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        vis[x]=0;
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int y=edge[i].to,z=edge[i].flow,c=edge[i].cost;
            if(dis[y]<dis[x]+c && z)
            {
                dis[y]=dis[x]+c,incf[y]=min(incf[x],z),pre[y]=i;
                if(!vis[y]) q.push(y),vis[y]=1;
            }
        }
    }
    return dis[t]!=dis[0];
}
void update()
{
    int x=t;
    while(x!=s)
    {
        int i=pre[x];
        edge[i].flow-=incf[t],edge[i^1].flow+=incf[t];
        x=edge[i^1].to;
    }
    maxcost+=dis[t]*incf[t];
}
int pos(int x,int y){return (x-1)*m+y;}
int main()
{
    cin>>a>>b>>n>>m;
    ++n,++m;
    s=n*m+1,t=n*m+2;
    int x,y,w;
    for(int i=1;i<=n;++i) for(int j=2;j<=m;++j) scanf("%d",&w),add(pos(i,j-1),pos(i,j),1,w),add(pos(i,j-1),pos(i,j),INF,0);
    for(int j=1;j<=m;++j) for(int i=2;i<=n;++i) scanf("%d",&w),add(pos(i-1,j),pos(i,j),1,w),add(pos(i-1,j),pos(i,j),INF,0);
    for(int i=1;i<=a;++i) scanf("%d %d %d",&w,&x,&y),add(s,pos(x+1,y+1),w,0);
    for(int i=1;i<=b;++i) scanf("%d %d %d",&w,&x,&y),add(pos(x+1,y+1),t,w,0);
    while(spfa()) update();
    cout<<maxcost;
    return 0;
}
/*
1 1
2 2
1 2
3 4
5 6
7 2
8 10
9 3
3 0 0
3 2 2
*/

上一题