• 费用流笔记


    费用流

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 #define inf 2147483647
     8 #define eps 1e-9
     9 using namespace std;
    10 typedef long long ll;
    11 struct edge{
    12     int v,w,z,next;
    13 }a[100001];
    14 int n,m,u,v,w,z,flw=0,ans=0,vs,vt,tot=1,head[50001],sp[50001],fr[50001];
    15 bool isin[50001];
    16 void add(int u,int v,int w,int z){
    17     a[++tot].v=v;
    18     a[tot].w=w;
    19     a[tot].z=z;
    20     a[tot].next=head[u];
    21     head[u]=tot;
    22     a[++tot].v=u;
    23     a[tot].w=0;
    24     a[tot].z=-z;
    25     a[tot].next=head[v];
    26     head[v]=tot;
    27 }
    28 bool spfa(){
    29     int mi=inf;
    30     queue<int>q;
    31     memset(isin,0,sizeof(isin));
    32     memset(sp,0x7f,sizeof(sp));
    33     q.push(vs);
    34     isin[vs]=true;
    35     sp[vs]=0;
    36     while(!q.empty()){
    37         int u=q.front();
    38         q.pop();
    39         isin[u]=false;
    40         for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
    41             int v=a[tmp].v;
    42             if(sp[v]>sp[u]+a[tmp].z&&a[tmp].w){
    43                 fr[v]=tmp;
    44                 sp[v]=sp[u]+a[tmp].z;
    45                 if(!isin[v]){
    46                     q.push(v);
    47                     isin[v]=true;
    48                 }
    49             }
    50         }
    51     }
    52     if(sp[vt]==0x7f7f7f7f)return false;
    53     for(int i=vt;i!=vs;i=a[fr[i]^1].v){
    54         mi=min(mi,a[fr[i]].w);
    55     }
    56     for(int i=vt;i!=vs;i=a[fr[i]^1].v){
    57         ans+=mi*a[fr[i]].z;
    58         a[fr[i]].w-=mi;
    59         a[fr[i]^1].w+=mi;
    60     }
    61     flw+=mi;
    62     return true;
    63 }
    64 int main(){
    65     memset(head,-1,sizeof(head));
    66     scanf("%d%d%d%d",&n,&m,&vs,&vt);
    67     for(int i=1;i<=m;i++){
    68         scanf("%d%d%d%d",&u,&v,&w,&z);
    69         add(u,v,w,z);
    70     }
    71     while(spfa());
    72     printf("%d %d",flw,ans);
    73     return 0;
    74 }

     UPD:zkw费用流

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 #define inf 2147483647
     8 #define eps 1e-9
     9 using namespace std;
    10 typedef long long ll;
    11 struct edge{
    12     int v,w,z,next;
    13 }a[100001];
    14 int n,m,u,v,w,z,vs,vt,tot=1,tt=0,flw=0,flow=0,ans=0,head[50001];
    15 bool vis[50001];
    16 void add(int u,int v,int w,int z){
    17     a[++tot].v=v;
    18     a[tot].w=w;
    19     a[tot].z=z;
    20     a[tot].next=head[u];
    21     head[u]=tot;
    22     a[++tot].v=u;
    23     a[tot].w=0;
    24     a[tot].z=-z;
    25     a[tot].next=head[v];
    26     head[v]=tot;
    27 }
    28 int aug(int u,int x){
    29     if(u==vt){
    30         ans+=flw*x;
    31         return x;
    32     }
    33     int mxf=x;
    34     vis[u]=true;
    35     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
    36         int v=a[tmp].v;
    37         if(a[tmp].w&&!a[tmp].z&&!vis[v]){
    38             int f=aug(v,min(x,a[tmp].w));
    39             a[tmp].w-=f;
    40             a[tmp^1].w+=f;
    41             mxf-=f;
    42             if(!mxf)return x;
    43         }
    44     }
    45     return x-mxf;
    46 }
    47 bool lab(){
    48     int mi=inf;
    49     for(int i=1;i<=n;i++){
    50         if(vis[i]){
    51             for(int tmp=head[i];tmp!=-1;tmp=a[tmp].next){
    52                 int v=a[tmp].v;
    53                 if(a[tmp].w&&!vis[v]){
    54                     mi=min(mi,a[tmp].z);
    55                 }
    56             }
    57         }
    58     }
    59     if(mi==inf)return false;
    60     for(int i=1;i<=n;i++){
    61         if(vis[i]){
    62             for(int tmp=head[i];tmp!=-1;tmp=a[tmp].next){
    63                 a[tmp].z-=mi;
    64                 a[tmp^1].z+=mi;
    65             }
    66         }
    67     }
    68     flw+=mi;
    69     return true;
    70 }
    71 int main(){
    72     memset(head,-1,sizeof(head));
    73     scanf("%d%d%d%d",&n,&m,&vs,&vt);
    74     for(int i=1;i<=m;i++){
    75         scanf("%d%d%d%d",&u,&v,&w,&z);
    76         add(u,v,w,z);
    77     }
    78     do{
    79         do{
    80             flow+=tt;
    81             memset(vis,0,sizeof(vis));
    82         }while(tt=aug(vs,inf));
    83     }while(lab());
    84     printf("%d %d",flow,ans);
    85     return 0;
    86 }
  • 相关阅读:
    C++右值引用的参考
    U3D 文档 GPU INSTANCING
    UNITY statistic中的 SetPass和Batches
    时间复杂度
    转,数组遍历的三种方式
    bug纪录:PhotonServer-14052: 17:14:09.033
    关于.net standard 与 .net core, net framework
    【转】未能加载文件或程序集或它的某一个依赖项,系统找不到指定的文件
    C# 计时函数精度测试
    一张图看懂dex
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/8945062.html
Copyright © 2020-2023  润新知