设为首页 加入收藏

TOP

POJ 2516 跑k次的最小费用最大流
2015-07-20 17:49:23 来源: 作者: 【 】 浏览:2
Tags:POJ 2516 最小 费用 最大

题目大意:给出n个客户对k个商品的需求量,又给出m个仓库对k个物品的存货量以及对k个物品从i仓库到j客户的一个物品的运费价格,让判断是否可以满足客户需求,然后就是如果满足求出最小的运费,是典型的最小费用最大流!

思路:可以将k中物品分开求最小费用最大流,然后想加得到总的最小费用最大流!

建图,对每个仓库是一个结点,每个客户也是一个结点,除此之外再加上s源点和t结束点!

1、s到仓库i的边的流量为仓库i的供给量,费用没有当然为0;

2、仓库i到客户j的流量为仓库的供给量,费用为仓库i到客户j的运输费用;

3、客户j到t的流量为客户的需求量,费用没有当然也为0;

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include
  
   
#include
   
     #include
    
      #include
     
       #include
       #include
       
         #include
        
          #include
         
           #include
          
            #define mem(a,b) memset(a,b,sizeof(a)) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define llson j<<1,l,mid #define rrson j<<1|1,mid+1,r #define INF 0x7fffffff typedef long long ll; typedef unsigned long long ull; using namespace std; #define maxn 20005 struct { int v,w,c,next,re; //re记录逆边的下标,c是费用,w是流量 } e[maxn]; int n,cnt; int head[maxn],que[maxn*8],pre[maxn],dis[maxn]; bool vis[maxn]; void add(int u, int v, int w, int c) { e[cnt].v=v,e[cnt].w=w,e[cnt].c=c; e[cnt].next=head[u]; e[cnt].re=cnt+1,head[u]=cnt++; e[cnt].v=u,e[cnt].w=0,e[cnt].c=-c; e[cnt].next=head[v]; e[cnt].re=cnt-1,head[v]=cnt++; } bool spfa() { int i, l = 0, r = 1; for(i = 0; i <= n; i ++) dis[i] = INF,vis[i] = false; dis[0]=0,que[0]=0,vis[0]=true; while(l
           
            dis[u]+e[i].c) { dis[v] = dis[u] + e[i].c; pre[v] = i; if(!vis[v]) { vis[v] = true; que[r++] = v; } } } vis[u] = false; } return dis[n]!=INF; } int change() { int i,p,sum=INF,ans=0; for(i=n;i!=0;i=e[e[p].re].v) {//e[e[p].re].v为前向结点,不理解看add和spfa p=pre[i];//p为前向结点编号 sum=min(sum,e[p].w); } for(i=n;i!=0;i=e[e[p].re].v) { p=pre[i]; e[p].w-=sum; e[e[p].re].w+=sum; ans+=sum*e[p].c;//c记录的为单位流量费用,必须得乘以流量。 } return ans; } int EK() { int sum=0; while(spfa()) sum+=change(); return sum; } void init() { mem(head,-1),mem(pre,0),cnt=0; } int a[51][51],b[51][51],cost[51][101],aa[51],bb[51]; int main() { //freopen("1.txt","r",stdin); int N,m,K; while(~scanf("%d%d%d",&N,&m,&K)) { if(!N&&!m&&!K) break; int i,j,k,flag=0,sum=0,s=0,t=m+N+1; mem(aa,0),mem(bb,0); for(i=1;i<=N;i++) for(j=1;j<=K;j++) { scanf("%d",&a[i][j]); aa[j]+=a[i][j]; } for(i=1;i<=m;i++) for(j=1;j<=K;j++) { scanf("%d",&b[i][j]); bb[j]+=b[i][j]; } for(i=1;i<=K;i++) if(bb[i]
            
             

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇二维数组与指针 下一篇UVA 1479 - Graph and Queries(Tr..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言中如何将结构体 (2025-12-24 22:20:09)
·纯C语言结构体成员变 (2025-12-24 22:20:06)
·C语言中,指针函数和 (2025-12-24 22:20:03)
·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)