zoukankan      html  css  js  c++  java
  • LuoguP4012 深海机器人问题(费用流)

    题目描述

    深海资源考察探险队的潜艇将到达深海的海底进行科学考察。

    潜艇内有多个深海机器人。潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动。

    深海机器人在移动中还必须沿途采集海底生物标本。沿途生物标本由最先遇到它的深海机器人完成采集。

    每条预定路径上的生物标本的价值是已知的,而且生物标本只能被采集一次。

    本题限定深海机器人只能从其出发位置沿着向北或向东的方向移动,而且多个深海机器人可以在同一时间占据同一位置。

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

    a行和b行输入时横纵坐标要反过来

    输出格式:

    输出采集到的生物标本的最高总价值.

    解题思路:

    输入喷我一脸。

    在边界建两条流,一条流量为1有费用,一条为0无费用

    代码:

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 const int oo=0x3f3f3f3f;
      6 struct pnt{
      7     int hd;
      8     int pre;
      9     int lst;
     10     int dis;
     11     int val;
     12     bool vis;
     13 }p[100000];
     14 struct ent{
     15     int twd;
     16     int lst;
     17     int vls;
     18     int dis;
     19 }e[1000000];
     20 int cnt;
     21 int n,m;
     22 int s,t;
     23 int ns,nt;
     24 int no[101][101];
     25 std::queue<int>Q;
     26 void ade(int f,int t,int v,int d)
     27 {
     28     cnt++;
     29     e[cnt].twd=t;
     30     e[cnt].vls=v;
     31     e[cnt].dis=d;
     32     e[cnt].lst=p[f].hd;
     33     p[f].hd=cnt;
     34     return ;
     35 }
     36 bool Spfa(void)
     37 {
     38     for(int i=1;i<=t;i++)
     39     {
     40         p[i].dis=p[i].val=oo;
     41         p[i].vis=false;
     42     }
     43     p[t].pre=-1;
     44     p[s].dis=0;
     45     p[s].vis=true;
     46     while(!Q.empty())
     47         Q.pop();
     48     Q.push(s);
     49     while(!Q.empty())
     50     {
     51         int x=Q.front();
     52         Q.pop();
     53         p[x].vis=false;
     54         for(int i=p[x].hd;i;i=e[i].lst)
     55         {
     56             int to=e[i].twd;
     57             if(p[to].dis>p[x].dis+e[i].dis&&e[i].vls>0)
     58             {
     59                 p[to].dis=p[x].dis+e[i].dis;
     60                 p[to].val=std::min(p[x].val,e[i].vls);
     61                 p[to].pre=x;
     62                 p[to].lst=i;
     63                 if(p[to].vis)
     64                     continue;
     65                 p[to].vis=true;
     66                 Q.push(to);
     67             }
     68         }
     69     }
     70     return p[t].pre!=-1;
     71 }
     72 int Ek(void)
     73 {
     74     int ans=0;
     75     while(Spfa())
     76     {
     77         ans+=p[t].dis*p[t].val;
     78         for(int i=t;i!=s;i=p[i].pre)
     79         {
     80             e[p[i].lst].vls-=p[t].val;
     81             e[((p[i].lst-1)^1)+1].vls+=p[t].val;
     82         }
     83     }
     84     return ans;
     85 }
     86 int main()
     87 {
     88 //    freopen("a.in","r",stdin);
     89     scanf("%d%d",&ns,&nt);
     90     scanf("%d%d",&n,&m);
     91     for(int i=0;i<=n;i++)
     92         for(int j=0;j<=m;j++)
     93             no[i][j]=++cnt;
     94     s=cnt+1;
     95     t=cnt+2;
     96     cnt=0;
     97     for(int i=0;i<=n;i++)
     98     {
     99         for(int j=0;j<m;j++)
    100         {
    101             int x;
    102             scanf("%d",&x);
    103             ade(no[i][j],no[i][j+1],1,-x);
    104             ade(no[i][j+1],no[i][j],0,x);
    105             ade(no[i][j],no[i][j+1],oo,0);
    106             ade(no[i][j+1],no[i][j],0,0);
    107         }
    108     }
    109     for(int j=0;j<=m;j++)
    110     {
    111         for(int i=0;i<n;i++)
    112         {
    113             int x;
    114             scanf("%d",&x);
    115             ade(no[i][j],no[i+1][j],1,-x);
    116             ade(no[i+1][j],no[i][j],0,x);
    117             ade(no[i][j],no[i+1][j],oo,0);
    118             ade(no[i+1][j],no[i][j],0,0);
    119         }
    120     }
    121     for(int i=1;i<=ns;i++)
    122     {
    123         int a,b,c;
    124         scanf("%d%d%d",&c,&a,&b);
    125         ade(s,no[a][b],c,0);
    126         ade(no[a][b],s,0,0);
    127     }
    128     for(int i=1;i<=nt;i++)
    129     {
    130         int a,b,c;
    131         scanf("%d%d%d",&c,&a,&b);
    132         ade(no[a][b],t,c,0);
    133         ade(t,no[a][b],0,0);
    134     }
    135     printf("%d
    ",-Ek());
    136     return 0;
    137 }
  • 相关阅读:
    mac 10.15.7 修改PATH
    oc 属性类型一般用法
    ubuntu解压zip文件名乱码
    telnet 退出
    docker 根据容器创建镜像
    mac android adb device 没有显示设备
    Yii2 查看所有的别名 alias
    Yii2 App Advanced 添加 .gitignore
    ubuntu 18.04 搜狗突然就提示乱码
    An error occured while deploying the file. This probably means that the app contains ARM native code and your Genymotion device cannot run ARM instructions. You should either build your native code to
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10210827.html
Copyright © 2011-2022 走看看