Luo Gu -3381 [template] Minimum Cost Maximum

Title Description
As stated, a network diagram is given, and the source and sink, each side units is known maximum flow and traffic charges, which determine the maximum flow and minimum cost network in the case of maximum flow.
Input format
The first line contains four positive integers N, M, S, T, respectively, the number of points, with a number of the edges, the source-point number, serial number sink.
Next M lines contains four integer ui, vi, wi, fi, denotes the i th ui from there to the edge and arriving at VI, the right side of wi (i.e., the side of the maximum flow rate Wi), per unit flow rate fee fi.
Format output
one line containing two integers, followed by the maximum flow and minimum cost at maximum flow conditions.

Sample Input Output
Input # 1
. 4. 3. 5. 4
. 4 2 30 2
. 4. 3 20 is. 3
2. 3. 1 20 is
2 30. 9. 1
. 1. 5 40. 3

Output # 1
50 280

Description / Tip
space constraints: 1000ms, 128M
(BYX: the last two points into 1200ms)
Data size:
for 30% of data: N <= 10, M < = 10
to 70% of the data: N <= 1000, M <= 1000
to 100% of the data: N <= 5000, M < = 50000

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=100010;
bool vis[maxn];
int n,m,s,t,x,y,z,f,dis[maxn],pre[maxn],last[maxn],flow[maxn],maxflow,mincost;
struct Edge{
    int to,next,flow,dis;
}edge[maxn];
int head[maxn],num_edge;
queue <int> q;
void add_edge(int from,int to,int flow,int dis){
    edge[++num_edge].next=head[from];
    edge[num_edge].to=to;
    edge[num_edge].flow=flow;
    edge[num_edge].dis=dis;
    head[from]=num_edge;
}
bool spfa(int s,int t){
    memset(dis,0x7f,sizeof(dis));
    memset(flow,0x7f,sizeof(flow));
    memset(vis,0,sizeof(vis));
    q.push(s); vis[s]=1; dis[s]=0; pre[t]=-1;
    while (!q.empty()){
        int now=q.front();
        q.pop();
        vis[now]=0;
        for (int i=head[now]; i!=-1; i=edge[i].next){
            if(edge[i].flow>0 && dis[edge[i].to]>dis[now]+edge[i].dis){
                dis[edge[i].to]=dis[now]+edge[i].dis;
                pre[edge[i].to]=now;
                last[edge[i].to]=i;
                flow[edge[i].to]=min(flow[now],edge[i].flow);
                if (!vis[edge[i].to]){
                    vis[edge[i].to]=1;
                    q.push(edge[i].to);
                }
            }
        }
    }
    return pre[t]!=-1;
}
void MCMF(){
    while (spfa(s,t)){
        int now=t;
        maxflow+=flow[t];
        mincost+=flow[t]*dis[t];
        while (now!=s){
            edge[last[now]].flow-=flow[t];
            edge[last[now]^1].flow+=flow[t];
            now=pre[now];
        }
    }
}
int main(){
    memset(head,-1,sizeof(head)); num_edge=-1;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for (int i=1; i<=m; i++){
        scanf("%d%d%d%d",&x,&y,&z,&f);
        add_edge(x,y,z,f); add_edge(y,x,0,-f);
    }
    MCMF();
    printf("%d %d",maxflow,mincost);
    return 0;
}

Guess you like

Origin blog.csdn.net/mkopvec/article/details/91906780