zoukankan      html  css  js  c++  java
  • 最小费用最大流模板

    用zkw模板跑了一下,简直吓尿。。。我的spfa模板跑需要3s,zkw模板才要0.1s。。。。。。。。。。差距太大了。。

    zkw模板还没来得及学,所以将spfa的模板搬上来吧。。

    最小费用最大流,就是每次用最短路算法找出增广路,增广即可。

    spfa未优化版本:

    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define CC(a, c) memset(a, c, sizeof(a))
    #define FOR(i,a,n) for(i=a;i<=n;++i)
    
    const int maxn=1000, maxm=1000000, oo=100000000;
    int cap[maxm], cost[maxm], d[maxn], p[maxn];
    int ihead[maxn], inext[maxm], to[maxm], from[maxm], cnt;
    queue<int> q; int vis[maxn];
    
    int min(const int& a, const int& b) { return a < b ? a : b; }
    
    void add(int u, int v, int c, int w) {
    	inext[++cnt]=ihead[u]; ihead[u]=cnt; from[cnt]=u; to[cnt]=v; cap[cnt]=c; cost[cnt]=w;
    	inext[++cnt]=ihead[v]; ihead[v]=cnt; from[cnt]=v; to[cnt]=u; cap[cnt]=0; cost[cnt]=0;
    }
    
    bool spfa(int s, int t, int n) {
    	int i, u;
    	FOR(i, 0, n) d[i]=oo; CC(vis, 0); CC(p, 0);
    	d[s]=0; q.push(s); vis[s]=1;
    	while(!q.empty()) {
    		u=q.front(); q.pop();
    		for(i=ihead[u]; i; i=inext[i]) if(cap[i]>0 && d[u]+cost[i]<d[to[i]]) {
    			d[to[i]]=d[u]+cost[i]; p[to[i]]=i;
    			if(!vis[to[i]]) { vis[to[i]]=1; q.push(to[i]); }
    		}
    		vis[u]=0;
    	}
    	return d[t]!=oo;
    }
    
    void mincost(int s, int t, int n, int& flow, int& mcost) {
    	int u, f;
    	while(spfa(s, t, n)) {
    		for(u=t, f=oo; u!=s; u=from[p[u]]) f=min(f, cap[p[u]]);
    		flow+=f; mcost+=f*d[t];
    		for(u=t; u!=s; u=from[p[u]]) {
    			cap[p[u]]-=f; cap[p[u]^1]+=f; cost[p[u]^1]=-cost[p[u]]; //这里要注意,反向弧的代价要等于正向弧的相反数,这样才能退流
    		}
    	}
    }
    
    void init() {
    	cnt=1; CC(ihead, 0);
    }
    
    int main() {
    	int n, m, u, v, c, w, i;
    	scanf("%d%d", &n, &m);
    	init();
    	for(i=1; i<=m; ++i) {
    		scanf("%d%d%d%d", &u, &v, &c, &w);
    		add(u, v, c, w);
    	}
    	int flow, mcost;
    	mincost(1, n, n, flow, mcost);
    	printf("%d
    ", mcost);
    	return 0;
    }
    
  • 相关阅读:
    【学习】Linux Shell脚本编程
    Linux 系统进程相关命令
    Linux 文件权限管理
    Linux 用户关联命令
    Linux shell 及命令汇总
    服务器通过树莓派控制继电器
    华为绩效管理:这样减员、增效、加薪,不服不行!!
    工作十年的程序员,却拿着毕业三年的工资,再不开窍就真晚了!
    员工离职原因,只有两点最真实,其他都是扯淡!
    最全面的2017物联网安全事件盘点
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3826486.html
Copyright © 2011-2022 走看看