洛谷 P3381 【模板】最小费用最大流(费用流)

题目链接:https://www.luogu.com.cn/problem/P3381

 

用SPFA求费用最短路,用pre记录路径,流量还是原来那样求。

 

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 const int N=50005;
 7 const int INF=0x3f3f3f;
 8 struct node{
 9     int from,to,flow,cost,next;
10 }edge[N<<1];
11 int head[N],pre[N],vis[N],dis[N];
12 int tot,n,m,s,t,flow,cost;
13 void init(){
14     memset(head,-1,sizeof(head));
15     tot=0;
16 }
17 void add(int u,int v,int flow,int cost){
18     edge[tot].from=u;
19     edge[tot].to=v;
20     edge[tot].flow=flow;
21     edge[tot].cost=cost;
22     edge[tot].next=head[u];
23     head[u]=tot++;
24     
25     edge[tot].from=v;
26     edge[tot].to=u;
27     edge[tot].flow=0;
28     edge[tot].cost=-cost;
29     edge[tot].next=head[v];
30     head[v]=tot++;
31 }
32 int spfa(int s,int t){
33     memset(dis,INF,sizeof(dis));
34     memset(vis,0,sizeof(vis));
35     memset(pre,-1,sizeof(pre));
36     queue<int> q;
37     q.push(s); dis[s]=0; vis[s]=1;
38     while(!q.empty()){
39         int u=q.front();
40         q.pop(); vis[u]=0;
41         for(int i=head[u];i!=-1;i=edge[i].next){
42             int v=edge[i].to;
43             if(edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
44                 dis[v]=dis[u]+edge[i].cost;
45                 pre[v]=i;
46                 if(vis[v]==0){
47                     q.push(v);
48                     vis[v]=1;
49                 }
50             }
51         }
52     }
53     if(pre[t]==-1) return 0;
54     return 1;
55 }
56 void MCMF(int s,int t){
57     cost=0,flow=0;
58     while(spfa(s,t)){
59         int minn=INF;
60         for(int i=pre[t];i!=-1;i=pre[edge[i].from]) 
61             minn=min(minn,edge[i].flow);
62         for(int i=pre[t];i!=-1;i=pre[edge[i].from]){
63             edge[i].flow-=minn;
64             edge[i^1].flow+=minn;
65         }
66         flow+=minn;
67         cost+=minn*dis[t];
68     }
69 }
70 int main(){
71     init();
72     scanf("%d%d%d%d",&n,&m,&s,&t);
73     for(int i=1;i<=m;i++){
74         int u,v,w,f;
75         scanf("%d%d%d%d",&u,&v,&w,&f);
76         add(u,v,w,f);
77     }
78     MCMF(s,t);
79     printf("%d %d",flow,cost);
80     return 0;
81 }
AC代码

 

posted @ 2020-08-19 19:32  dfydn  阅读(128)  评论(1编辑  收藏  举报