zoukankan      html  css  js  c++  java
  • [网络流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     }
  • 相关阅读:
    Java SSM入门(十三)——Oracle(二)(PLSQL)
    Java SSM入门(十二)——Oracle(一)(增删改查)
    Java SSM入门(十一)——SSM整合
    JAVA网络编程
    容器随笔
    Java容器
    Java面向对象
    Java Lambda表达式
    Java数组详解
    需要注意的
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8454452.html
Copyright © 2011-2022 走看看