zoukankan      html  css  js  c++  java
  • Minimum Cost POJ

    k种商品的源汇分配

    朴素的算k次最大流,没人知道如果数据大怎么办吗。。。

    //#include<bits/stdc++.h>
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    
    using namespace std;
    #define ll long long
    const int maxn=5e5+5;
    const int maxm=5e5+7;
    const int inf=0x3f3f3f3f;
    struct EDGE{
    	int to,next,cap,flow,cost;
    }edge[maxn];
    int head[maxn],tot;
    int pre[maxn],dis[maxn];
    int vis[maxn];
    
    int source,sink;
    int num_nodes;
    
    void init(){
    	tot=0;
    	memset(head,-1,sizeof head);
    }
    void addedge(int u,int v,int cap,int cost){
    	edge[tot]=(EDGE){v,head[u],cap,0,cost};
    	head[u]=tot++;
    	edge[tot]=(EDGE){u,head[v],0,0,-cost};
    	head[v]=tot++;
    }
    int spfa(int s,int t){
    	queue<int>Q;
    	for(int i=0;i<num_nodes;i++){
    		dis[i]=inf;
    		vis[i]=0;
    		pre[i]=-1;
    	}
    	dis[s]=0;
    	vis[s]=1;
    	Q.push(s);
    	while(!Q.empty()){
    		//cout<<"wwww"<<endl;
    		int u=Q.front();
    		Q.pop();
    		vis[u]=0;
    		for(int i=head[u];~i;i=edge[i].next){
    			int v=edge[i].to;
    			if(edge[i].cap>edge[i].flow && dis[v]>dis[u]+edge[i].cost){
    				dis[v]=dis[u]+edge[i].cost;
    				pre[v]=i;
    				if(!vis[v]){
    					vis[v]=1;
    					Q.push(v);
    				}
    			}
    		}
    	}
    	if(pre[t]==-1)return 0;
    	return 1;
    }
    int mcmf(int &cost){
    	int s=source,t=sink;
    	int flow=0;
    	cost=0;
    	while(spfa(s,t)){
    
    		int minflow=inf;
    		for(int i=pre[t];~i;i=pre[edge[i^1].to]){
    			minflow=min(minflow,edge[i].cap-edge[i].flow);
    		}
    		for(int i=pre[t];~i;i=pre[edge[i^1].to]){
    			edge[i].flow+=minflow;
    			edge[i^1].flow-=minflow;
    			cost+=edge[i].cost*minflow;
    		}
    		flow+=minflow;
    	}
    	return flow;
    }
    
    int sup[55][55];//第i个供应商有几个j号商品
    int ned[55][55];//第i个需求者要几个j号商品
    int spt[55][55];//第j个供应给第i个的花费
    
    int main(){
    	int n,m,k;//50, m种源,n个汇,k种物品
    	while(~scanf("%d%d%d",&n,&m,&k)&&n){
    
    		num_nodes=n+m+2;
    		
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=k;j++){
    				scanf("%d",&ned[i][j]);
    			}
    		}
    		for(int i=1;i<=m;i++){
    			for(int j=1;j<=k;j++){
    				scanf("%d",&sup[i][j]);
    			}
    		}
    		int fail=0;	
    		for(int i=1;i<=k;i++){
    			int cmp1=0,cmp2=0;
    			for(int j=1;j<=m;j++)cmp1+=sup[j][i];
    			for(int j=1;j<=n;j++)cmp2+=ned[j][i];
    			if(cmp1<cmp2)fail=1;			
    		}
    			
    		source=0;
    		sink=n+m+1;
    
    		int ans=0;
    		for(int i=1;i<=k;i++){//k个花费矩阵
    			init();
    			for(int j=1;j<=n;j++){
    				for(int q=1;q<=m;q++){
    					scanf("%d",&spt[j][q]);
    					addedge(q,j+m,inf,spt[j][q]);
    				}
    			}
    			if(fail)continue;
    			for(int j=1;j<=m;j++){
    				addedge(0,j,sup[j][i],0);
    			}
    			for(int j=1;j<=n;j++){
    				addedge(j+m,sink,ned[j][i],0);
    			}
    			int costt;mcmf(costt);
    			ans+=costt;
    
    		}
    		if(fail){
    			printf("-1
    ");
    		}else
    		printf("%d
    ",ans);
    	}	
    }

    也算是一种模型了吧,虽说比起下面要见到的来说简单太多。。

  • 相关阅读:
    返回图片宽高比
    3.1/3.2图片上传类
    php获取图片的拍摄及其他数据信息
    上传类
    pathinfo()的用法
    上传并压缩图片
    将数组转化为键值对
    css3判断某个li标签
    禁止滚动条/启用滚动条
    Keepalived + haproxy双机高可用方案
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611311.html
Copyright © 2011-2022 走看看