zoukankan      html  css  js  c++  java
  • 深海机器人(cogs 742)

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

    /*
        费用流。
        因为每条边可以随便走,并且只能获利一次,所以把每条边拆成两条边,
        一条容量为1,费用为w,另一条容量无限,费用为0。
        注意体面中的x,y坐标比较坑。 
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #define N 1010
    #define inf 1000000000
    using namespace std;
    int head[N],dis[N],inq[N],fa[N],a,b,P,Q,S,T,cnt=1;
    struct node{int v,f,w,pre;}e[N*10];
    queue<int> q;
    void add(int u,int v,int f,int w){
        e[++cnt].v=v;e[cnt].f=f;e[cnt].w=w;e[cnt].pre=head[u];head[u]=cnt;
        e[++cnt].v=u;e[cnt].f=0;e[cnt].w=-w;e[cnt].pre=head[v];head[v]=cnt;
    }
    bool spfa(){
        for(int i=0;i<=T;i++) dis[i]=inf;
        dis[S]=0;q.push(S);
        while(!q.empty()){
            int u=q.front();q.pop();inq[u]=0;
            for(int i=head[u];i;i=e[i].pre)
                if(e[i].f&&dis[e[i].v]>dis[u]+e[i].w){
                    dis[e[i].v]=dis[u]+e[i].w;
                    fa[e[i].v]=i;
                    if(!inq[e[i].v]){
                        inq[e[i].v]=1;
                        q.push(e[i].v);
                    }
                }
        }
        return dis[T]!=inf;
    }
    int updata(){
        int i=fa[T],x=inf;
        while(i){
            x=min(x,e[i].f);
            i=fa[e[i^1].v];
        }
        i=fa[T];
        while(i){
            e[i].f-=x;
            e[i^1].f+=x;
            i=fa[e[i^1].v];
        }
        return x*dis[T];
    }
    int id(int x,int y){return (x-1)*Q+y;}
    int main(){
        freopen("shinkai.in","r",stdin);
        freopen("shinkai.out","w",stdout);
        scanf("%d%d%d%d",&a,&b,&P,&Q);P++;Q++;
        S=0;T=P*Q+1;
        for(int i=1;i<=P;i++)
            for(int j=1;j<Q;j++){
                int x;scanf("%d",&x);
                add(id(i,j),id(i,j+1),1,-x);
                add(id(i,j),id(i,j+1),inf,0);
            }
        for(int j=1;j<=Q;j++)
            for(int i=1;i<P;i++){
                int x;scanf("%d",&x);
                add(id(i,j),id(i+1,j),1,-x);
                add(id(i,j),id(i+1,j),inf,0);
                
            }
        for(int i=1;i<=a;i++){
            int k,x,y;scanf("%d%d%d",&k,&x,&y);
            add(S,id(x+1,y+1),k,0);
        }
        for(int i=1;i<=b;i++){
            int k,x,y;scanf("%d%d%d",&k,&x,&y);
            add(id(x+1,y+1),T,k,0);
        }
        int minv=0;
        while(spfa())
            minv+=updata();
        printf("%d",-minv);
        return 0;
    }
  • 相关阅读:
    SQL_Server_2005_启用远程连接
    Oracle外网或内网远程连接
    还原数据库到指定时间点
    SQL Server账号密码(sa)登录失败 错误原因:18456
    sql server如何设置密码过期时间呢?
    安装SQL Server2014 :规则”Windows Management Instrumentation (WMI)服务 “失败
    impala
    dolphinscheduler
    829. Consecutive Numbers Sum 连续的数字求和
    472. Concatenated Words 查找自己拼出来的单词 反向word break
  • 原文地址:https://www.cnblogs.com/harden/p/6711190.html
Copyright © 2011-2022 走看看