Spfa费用流模板

 1 const int INF=1000000000;
 2 const int maxn=1010,maxm=400010;
 3 int cnt=1,fir[maxn],nxt[maxm],to[maxm];
 4 int cap[maxm],val[maxm],dis[maxn],path[maxn];
 5 
 6 void add(int a,int b,int c,int v){
 7     nxt[++cnt]=fir[a];to[cnt]=b;
 8     cap[cnt]=c;val[cnt]=v;fir[a]=cnt;
 9 }
10 void addedge(int a,int b,int c,int v){
11     add(a,b,c,v);
12     add(b,a,0,-v);
13 }
14 
15 int S,T;
16 int vis[maxn];
17 int Spfa(){
18     deque<int>q;
19     memset(dis,127,sizeof(dis));
20     memset(vis,0,sizeof(vis));
21     q.push_front(S);
22     dis[S]=0;vis[S]=1;
23     while(!q.empty()){
24         int x=q.front();q.pop_front();vis[x]=0;
25         for(int i=fir[x];i;i=nxt[i])
26             if(cap[i]&&dis[x]+val[i]<dis[to[i]]){
27                 dis[to[i]]=val[i]+dis[x];
28                 path[to[i]]=i;
29                 if(vis[to[i]])continue;
30                 if(dis[to[i]]<dis[x])
31                     q.push_front(to[i]);
32                 else
33                     q.push_back(to[i]);
34                 vis[to[i]]=1;    
35             }
36     }
37     return dis[T]==dis[T+1]?0:dis[T]; 
38 }
39 
40 int Aug(){
41     int p=T,f=INF;
42     while(p!=S){
43         f=min(f,cap[path[p]]);
44         p=to[path[p]^1];
45     }
46     p=T;
47     while(p!=S){
48         cap[path[p]]-=f;
49         cap[path[p]^1]+=f;
50         p=to[path[p]^1];
51     }
52     return f;
53 }
54 
55 int MCMF(){
56     int ret=0,d;
57     while(d=Spfa())
58         ret+=Aug()*d;
59     return ret;    
60 }

 

 1 #include <queue>
 2 using namespace std;
 3 const int maxn=2010;
 4 const int maxm=500010;
 5 const int INF=1061109567;
 6 int n,m,w[maxn],cnt,fir[maxn],to[maxm],nxt[maxm];
 7 int cap[maxm],val[maxm],path[maxn],vis[maxn],dis[maxn];
 8 queue<int>q;
 9 struct Net_Flow{
10     Net_Flow(){cnt=1;}
11     
12     void add(int a,int b,int c,int v){
13         nxt[++cnt]=fir[a];cap[cnt]=c;
14         to[cnt]=b;val[cnt]=v;fir[a]=cnt;
15     }
16     
17     void addedge(int a,int b,int c,int v){
18         add(a,b,c,v);add(b,a,0,-v);
19     }
20     
21     int Spfa(int S,int T){
22         memset(dis,63,sizeof(dis));
23         q.push(S);vis[S]=1;dis[S]=0;
24         while(!q.empty()){
25             int x=q.front();q.pop();vis[x]=0;
26             for(int i=fir[x];i;i=nxt[i])
27                 if(cap[i]&&dis[to[i]]>dis[x]+val[i]){
28                     dis[to[i]]=dis[x]+val[i];
29                     if(!vis[to[i]])q.push(to[i]);
30                     vis[to[i]]=1;path[to[i]]=i;
31                 }
32         }
33         return dis[T];
34     }
35     
36     int Aug(int S,int T){
37         int p=T,f=INF;
38         while(p!=S){
39             f=min(f,cap[path[p]]);
40             p=to[path[p]^1];
41         }p=T;
42         while(p!=S){
43             cap[path[p]]-=f;
44             cap[path[p]^1]+=f;
45             p=to[path[p]^1];
46         }
47         return f;
48     }
49     
50     int MCMF(int S,int T){
51         int v=0,d;
52         while((d=Spfa(S,T))!=INF)
53             v+=d*Aug(S,T);
54         return v;
55     }
56 }mcmf;

 

转载于:https://www.cnblogs.com/TenderRun/p/5222617.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值