• 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 }
  • 相关阅读:
    SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段值)
    Web Api 跨域解决方案
    Web Api Session开启会话支持
    Web Service 学习
    省市选择器
    如何创建圆形头像和圆角图片
    E
    二叉树
    素数筛法
    Color Me Less
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10210827.html
Copyright © 2020-2023  润新知