[网络流24题] 深海机器人问题

题面:

传送门

思路:

有些点入,有些点出,每条边上都有价值.,....

多么完美的最大费用最大流!

那么怎么实现让每条边上的价值只被计算一次呢?

建两条边,一条边费用为这条边的价值,流量为1,另一条边费用0,流量inf即可

然后入口和出口连源汇点,跑最大费用最大流即可

欧拉!

Code:

 

 1     #include<iostream>
 2     #include<cstdio>
 3     #include<algorithm>
 4     #include<cstring>
 5     #define inf 1e9
 6     #define id(i,j) (i-1)*(n+1)+j
 7     using namespace std;
 8     inline int read(){
 9         int re=0,flag=1;char ch=getchar();
10         while(ch<'0'||ch>'9'){
11             if(ch=='-') flag=-1;
12             ch=getchar();
13         }
14         while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
15         return re*flag;
16     }
17     int n,m,p,q,cnt,ans,flow,first[1000],dis[1000],pre[1000],path[1000];
18     bool vis[1000];
19     struct edge{
20         int to,next,w,cap;
21     }a[200010];
22     inline void add(int u,int v,int w,int cap){
23         a[++cnt]=(edge){v,first[u],-w,cap};first[u]=cnt;
24         a[++cnt]=(edge){u,first[v],w,0};first[v]=cnt;
25     }
26     bool spfa(int s,int t){
27         memset(pre,-1,sizeof(pre));memset(path,-1,sizeof(path));
28         memset(vis,0,sizeof(vis));
29         int u,v,i,q[5010],head=0,tail=1;
30         for(i=s;i<=t;i++) dis[i]=inf;
31         q[0]=s;dis[s]=0;vis[s]=1;
32         while(head<tail){
33             u=q[head++];vis[u]=0;
34             for(i=first[u];~i;i=a[i].next){
35                 v=a[i].to;
36                 if(dis[u]+a[i].w<dis[v]&&a[i].cap>0){
37                     dis[v]=dis[u]+a[i].w;
38                     pre[v]=u;path[v]=i;
39                     if(!vis[v]) q[tail++]=v,vis[v]=1;
40                 }
41             }
42         }
43         return ~pre[t];
44     }
45     void mcmf(int s,int t){
46         int u,f;
47         while(spfa(s,t)){
48             f=inf;
49             for(u=t;u!=s;u=pre[u]) f=min(f,a[path[u]].cap);
50             flow+=f;ans+=f*dis[t];
51             for(u=t;u!=s;u=pre[u]){
52                 a[path[u]].cap-=f;
53                 a[path[u]^1].cap+=f;
54             }
55         }
56     }
57     void init(){
58         memset(first,-1,sizeof(first));memset(a,0,sizeof(a));
59         cnt=-1;ans=0;flow=0;
60     }
61     int main(){
62         freopen("shinkai.in","r",stdin);
63         freopen("shinkai.out","w",stdout);
64         init();
65         int i,j,t1,t2,t3;
66         p=read();q=read();m=read();n=read();
67         for(i=1;i<=m+1;i++){
68             for(j=1;j<=n;j++){
69                 t1=read();
70                 add(id(i,j),id(i,j+1),t1,1);
71                 add(id(i,j),id(i,j+1),0,inf);    
72             } 
73         }
74         for(j=1;j<=n+1;j++){
75             for(i=1;i<=m;i++){
76                 t1=read();
77                 add(id(i,j),id(i+1,j),t1,1);
78                 add(id(i,j),id(i+1,j),0,inf);
79             }
80         }
81         for(i=1;i<=p;i++){
82             t1=read();t2=read();t3=read();
83             add(0,id(t2+1,t3+1),0,t1);
84         }
85         for(i=1;i<=q;i++){
86             t1=read();t2=read();t3=read();
87             add(id(t2+1,t3+1),id(n+1,m+1)+1,0,t1);
88         }
89         mcmf(0,id(n+1,m+1)+1);
90         printf("%d",-ans);
91     }

 

posted @ 2018-02-19 21:20  dedicatus545  阅读(139)  评论(0编辑  收藏  举报