• 【洛谷 p3381】模板-最小费用最大流(图论)


    题目:给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。

    解法:在Dinic的基础下做spfa算法。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<queue>
     6 using namespace std;
     7 
     8 const int N=5010,M=50010,INF=(int)1e9;
     9 int n,m,st,ed,len=1;
    10 int last[N],vis[N],id[N],pre[N],flow[N],d[N];
    11 struct node{int y,fl,co,next;}a[2*M];
    12 queue<int> q;
    13 
    14 int mmin(int x,int y) {return x<y?x:y;}
    15 void ins(int x,int y,int fl,int co)
    16 {
    17     a[++len].y=y,a[len].fl=fl,a[len].co=co;
    18     a[len].next=last[x],last[x]=len;
    19     a[++len].y=x,a[len].fl=0,a[len].co=-co;
    20     a[len].next=last[y],last[y]=len;
    21 }
    22 bool spfa()
    23 {
    24     while (!q.empty()) q.pop();
    25     for (int i=1;i<=n;i++) d[i]=INF;
    26     memset(vis,0,sizeof(vis));
    27     q.push(st);
    28     d[st]=0,vis[st]=1,flow[st]=INF;
    29     while (!q.empty())
    30     {
    31       int x=q.front();
    32       q.pop(); vis[x]=0;
    33       for (int i=last[x];i!=-1;i=a[i].next)
    34       {
    35         int y=a[i].y;
    36         if (!a[i].fl) continue;
    37         if (d[x]+a[i].co<d[y])
    38         {
    39           d[y]=d[x]+a[i].co;
    40           flow[y]=mmin(flow[x],a[i].fl);
    41           id[y]=i, pre[y]=x;
    42           if (!vis[y]) q.push(y), vis[y]=1;
    43         }
    44       }
    45     }
    46     return (d[ed]!=INF);
    47 }
    48 void Max_flow()
    49 {
    50     int sum=0,cost=0;;
    51     while (spfa())
    52     {
    53       sum+=flow[ed],cost+=d[ed]*flow[ed];
    54       for (int i=ed;i!=st;i=pre[i])
    55       {
    56         a[id[i]].fl-=flow[ed];
    57         a[id[i]^1].fl+=flow[ed];
    58       }
    59     }
    60     printf("%d %d
    ",sum,cost);
    61 }
    62 int main()
    63 {
    64     scanf("%d%d%d%d",&n,&m,&st,&ed);
    65     int x,y,fl,co;
    66     memset(last,-1,sizeof(last));
    67     for (int i=1;i<=m;i++)
    68     {
    69       scanf("%d%d%d%d",&x,&y,&fl,&co);
    70       ins(x,y,fl,co);
    71     }
    72     Max_flow();
    73     return 0;
    74 }
  • 相关阅读:
    Android Activity
    Android 五大布局
    Android 使用线性布局LinearLayout和Button实现一个点红块游戏
    邻接表、逆邻接表
    view的绘制原理
    IPC机制
    图的深度优先遍历
    最短路径算法
    几种编码方式
    Android APK反编译问题
  • 原文地址:https://www.cnblogs.com/konjak/p/6074894.html
Copyright © 2020-2023  润新知