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\n",-Ek());
136     return 0;
137 }
posted @ 2019-01-02 20:02  Unstoppable728  阅读(175)  评论(0编辑  收藏  举报