zoukankan      html  css  js  c++  java
  • 网络流之最小费最大流

    网络流之最小费最大流

    例题

    题目:n个人,m个房,要求每个人都回房间且路程和最短,每个人都回房间就是最大流为n,同时要求路程和最短就是还要要求费用最小了。

    相较于最大流,要求跑最大流的同时要求费用最低,那么我们便不能够,将dfs的路径全部加入答案,因为里面费用可能会花的更多,所以我们只能降低效率,每次只增广一条最短路,用spfa找最短路,并记录路径后更新最大流于费用即可。

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define ll long long
    const ll inf=1e18;
    int st,fi,n,m,tot,head[1000007],vis[1000007],pe[1000007],pn[1000007];
    ll fw,dis[1000007],ans;
    char s[107][107];
    vector<pair<int,int> >H,M;
    struct madoka{
    	int to;
    	int next;
    	ll w;
    	ll z;
    }e[1000007];
    void add(int u,int v,ll w,ll z){
    	e[++tot].to=v;
    	e[tot].next=head[u];
    	e[tot].w=w;
    	e[tot].z=z;
    	head[u]=tot;
    	e[++tot].to=u;
    	e[tot].next=head[v];
    	e[tot].w=0;
    	e[tot].z=-z;
    	head[v]=tot;
    }
    bool spfa(){
    	queue<int>sa;
    	for(int i=1;i<=fi;i++){
    		dis[i]=inf;
    		vis[i]=0;
    	}
    	sa.push(st);
    	dis[st]=0;
    	vis[st]=1;
    	while(!sa.empty()){
    		int p=sa.front();
    		sa.pop();
    		vis[p]=0;
    		for(int i=head[p];i!=0;i=e[i].next){
    			int to=e[i].to;
    			if(e[i].w&&dis[p]+e[i].z<dis[to]){
    				dis[to]=dis[p]+e[i].z;
    				pn[to]=p;
    				pe[to]=i;
    				if(vis[to]==0){
    					vis[to]=1;
    					sa.push(to);
    				}
    			}
    		}
    	}
    	if(dis[fi]==inf){
    		return 0;
    	}
    	return 1;
    }
    ll go(int p,ll now){
    	if(p==st)return now;
    	ll lin=go(pn[p],min(now,e[pe[p]].w));
    	e[pe[p]].w-=lin;
    	e[pe[p]^1].w+=lin;
    	return lin;
    }
    void dinic(){
    	fw=0;
    	ans=0;
    	while(spfa()){
    		ll now=go(fi,inf);
    		fw+=now;
    		ans+=dis[fi]*now;
    	}
    }
    void init(){
    	tot=1;
    	memset(head,0,sizeof(head));
    	M.clear();
    	H.clear();
    }
    int main(){
    	while(1){
    		init();
    		scanf("%d%d",&n,&m);
    		if(n==0&&m==0)break;
    		for(int i=1;i<=n;i++){
    			scanf("%s",s[i]+1);
    		}
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=m;j++){
    				if(s[i][j]=='m'){
    					M.push_back({i,j});
    				}
    				if(s[i][j]=='H'){
    					H.push_back({i,j});
    				}
    			}
    		}
    		st=M.size()+H.size()+1;
    		fi=M.size()+H.size()+2;
    		for(int i=0;i<M.size();i++){
    			add(st,i+1,1,0);
    		}
    		for(int i=0;i<H.size();i++){
    			add(M.size()+i+1,fi,1,0);
    		}
    		for(int i=0;i<M.size();i++){
    			for(int j=0;j<H.size();j++){
    				add(i+1,M.size()+j+1,1,abs(M[i].first-H[j].first)+abs(M[i].second-H[j].second));
    			}
    		}
    		dinic();
    		printf("%lld
    ",ans);
    	}
    }
    
  • 相关阅读:
    轻量级数据库sqlite的使用
    Integer引发的思考
    css限制显示行数
    数据库 chapter 17 数据仓库与联机分析处理技术
    数据库 chapter 15 对象关系数据库系统
    数据库 chapter 16 XML数据库
    数据库 chapter 14 分布式数据库系统
    数据库 chapter 11 并发控制
    数据库 chapter 12 数据库管理系统
    数据库 chapter 13 数据库技术新发展
  • 原文地址:https://www.cnblogs.com/whitelily/p/14034765.html
Copyright © 2011-2022 走看看