【PowerOJ1755&网络流24题】深海机器人问题(费用流)

题意:

 

 思路:

【问题分析】

最大费用最大流问题。

【建模方法】

把网格中每个位置抽象成网络中一个节点,建立附加源S汇T。

1、对于每个顶点i,j为i东边或南边相邻的一个节点,连接节点i与节点j一条容量为1,费用为该边价值的有向边。

2、对于每个顶点i,j为i东边或南边相邻的一个节点,连接节点i与节点j一条容量为无穷大,费用为0的有向边。

3、从S到每个出发点i连接一条容量为该点出发的机器人数量,费用为0的有向边。

4、从每个目标点i到T连接一条容量为可以到达该点的机器人数量,费用为0的有向边。

求最大费用最大流,最大费用流值就采集到的生物标本的最高总价值。

【建模分析】

这个问题可以看做是多出发点和目的地的网络运输问题。每条边的价值只能计算一次,容量限制要设为1。同时还将要连接上容量不限,费用为0的重边。由于“多个深海机器人可以在同一时间占据同一位

置”,所以不需限制点的流量,直接求费用流即可。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef long double ld;
  7 typedef pair<int,int> PII;
  8 typedef pair<ll,ll> Pll;
  9 typedef vector<int> VI;
 10 typedef vector<PII> VII;
 11 typedef pair<ll,ll>P;
 12 #define N  50000
 13 #define M  1000000
 14 #define INF 1e9
 15 #define fi first
 16 #define se second
 17 #define MP make_pair
 18 #define pb push_back
 19 #define pi acos(-1)
 20 #define mem(a,b) memset(a,b,sizeof(a))
 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 23 #define lowbit(x) x&(-x)
 24 #define Rand (rand()*(1<<16)+rand())
 25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 26 #define ls p<<1
 27 #define rs p<<1|1
 28 
 29 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 30       double eps=1e-6;
 31       int dx[4]={-1,1,0,0};
 32       int dy[4]={0,0,-1,1};
 33 
 34 int head[N],vet[N],nxt[N],len1[N],len2[N],dis[N],inq[N],a[N],q[N],pre[N][2],num[500][500],
 35     s,S,T,ans1,ans2,tot;
 36 
 37 int read()
 38 {
 39    int v=0,f=1;
 40    char c=getchar();
 41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 43    return v*f;
 44 }
 45 
 46 void add(int a,int b,int c,int d)
 47 {
 48     nxt[++tot]=head[a];
 49     vet[tot]=b;
 50     len1[tot]=c;
 51     len2[tot]=d;
 52     head[a]=tot;
 53 
 54     nxt[++tot]=head[b];
 55     vet[tot]=a;
 56     len1[tot]=0;
 57     len2[tot]=-d;
 58     head[b]=tot;
 59 }
 60 
 61 int spfa()
 62 {
 63     rep(i,1,s)
 64     {
 65         dis[i]=-INF;
 66         inq[i]=0;
 67     }
 68     int t=0,w=1;
 69     q[1]=S; dis[S]=0; inq[S]=1;
 70     while(t<w)
 71     {
 72         t++; int u=q[t%(s+5)]; inq[u]=0;
 73         int e=head[u];
 74         while(e)
 75         {
 76             int v=vet[e];
 77             if(len1[e]&&dis[u]+len2[e]>dis[v])
 78             {
 79                 dis[v]=dis[u]+len2[e];
 80                 pre[v][0]=u;
 81                 pre[v][1]=e;
 82                 if(!inq[v])
 83                 {
 84                     w++; q[w%(s+5)]=v; inq[v]=1;
 85                 }
 86             }
 87             e=nxt[e];
 88         }
 89     }
 90     if(dis[T]==-INF) return 0;
 91     return 1;
 92 }
 93 
 94 void mcf()
 95 {
 96     int k=T,t=INF;
 97     while(k!=S)
 98     {
 99         int e=pre[k][1];
100         t=min(t,len1[e]);
101         k=pre[k][0];
102     }
103     ans1+=t;
104     k=T;
105     while(k!=S)
106     {
107         int e=pre[k][1];
108         len1[e]-=t;
109         len1[e^1]+=t;
110         ans2+=t*len2[e];
111         k=pre[k][0];
112     }
113 
114 }
115 
116 int main()
117 {
118     //freopen("1.in","r",stdin);
119     int a=read(),b=read();
120     int n=read(),m=read();
121     s=0;
122     rep(i,0,n)
123      rep(j,0,m) num[i][j]=++s;
124     S=++s,T=++s;
125     rep(i,1,s) head[i]=0;
126     tot=1;
127     rep(i,0,n)
128      rep(j,0,m-1)
129      {
130          int x=read();
131          add(num[i][j],num[i][j+1],1,x);
132          add(num[i][j],num[i][j+1],INF,0);
133      }
134     rep(i,0,m)
135      rep(j,0,n-1)
136      {
137          int x=read();
138          add(num[j][i],num[j+1][i],1,x);
139          add(num[j][i],num[j+1][i],INF,0);
140      }
141     rep(i,1,a)
142     {
143         int k=read(),x=read(),y=read();
144         add(S,num[x][y],k,0);
145     }
146     rep(i,1,b)
147     {
148         int r=read(),x=read(),y=read();
149         add(num[x][y],T,r,0);
150     }
151     tot=1;
152     ans1=ans2=0;
153     while(spfa()) mcf();
154     printf("%d\n",ans2);
155     return 0;
156 
157 }

 

posted on 2019-10-30 18:19  myx12345  阅读(152)  评论(0编辑  收藏  举报

导航