首先对于一种商品

如果这种货不足需求就直接输出-1

剩下的就是KM算法

分k次分别计算每种商品的最小权值匹配

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,k,shop[][],sup[][],cost[][][],edges[][],cntA,cntB;
int belongA[],belongB[],A[],B[],visA[],visB[],mat[],d;
int dfs(int i)
{
visA[i]=;
for (int j=;j<=cntB;j++)
if (!visB[j]&&edges[i][j])
{
int t=edges[i][j]-A[i]-B[j];
if (!t)
{
visB[j]=;
if (!mat[j]||dfs(mat[j]))
{
mat[j]=i;
return ;
}
}
else d=min(d,t);
}
return ;
}
int match()
{
memset(A,0x3f,sizeof(A));
memset(B,,sizeof(B));
for (int i=;i<=cntA;i++)
for (int j=;j<=cntB;j++)A[i]=min(A[i],edges[i][j]);
memset(mat,,sizeof(mat));
for (int i=;i<=cntA;i++)
{
while ()
{
memset(visA,,sizeof(visA));
memset(visB,,sizeof(visB));
d=1e9;
if (dfs(i))break;
for (int j=;j<=cntA;j++)
if (visA[j]) A[j]+=d;
for (int j=;j<=cntB;j++)
if (visB[j]) B[j]-=d;
}
}
int ans=;
for (int i=;i<=cntB;i++)ans+=edges[mat[i]][i];
return ans;
}
int main()
{
while (~scanf("%d%d%d",&n,&m,&k),n+m+k)
{
for (int i=;i<=n;i++)
for (int j=;j<=k;j++)scanf("%d",&shop[i][j]);
for (int i=;i<=m;i++)
for (int j=;j<=k;j++)scanf("%d",&sup[i][j]);
for (int t=;t<=k;t++)
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)scanf("%d",&cost[t][i][j]);
int flag=;
for (int i=;i<=k;i++)
{
int need=,have=;
for (int j=;j<=n;j++)need+=shop[j][i];
for (int j=;j<=m;j++)have+=sup[j][i];
if (need>have)
{
flag=;
puts("-1");
break;
}
}
if (!flag)continue;
int ans=;
for (int t=;t<=k;t++)
{
cntA=cntB=;
for (int i=;i<=n;i++)
for (int j=;j<=shop[i][t];j++)belongA[++cntA]=i;
for (int i=;i<=m;i++)
for (int j=;j<=sup[i][t];j++)belongB[++cntB]=i;
for (int i=;i<=cntA;i++)
for (int j=;j<=cntB;j++)
edges[i][j]=cost[t][belongA[i]][belongB[j]];
ans+=match();
}
printf("%d\n",ans);
}
return ;
}

poj21516的更多相关文章

随机推荐

  1. 使用 vim + ctags + cscope + taglist 阅读源码

    转自:http://my.oschina.net/u/554995/blog/59927 最近,准备跟学长一起往 linux kernel 的门里瞧瞧里面的世界,虽然我们知道门就在那,但我们还得找到合 ...

  2. 【java】使用Builder模式,轻松应对动态繁杂的方法参数

    背景:在咱编写的图片处理模块里,针对加载这个方法,参数很多,如: /** * 加载图片,经过内存.磁盘.两层缓存如果还没找到,则走http访问网络资源 * @param url 地址 * @param ...

  3. Java-线程池专题(什么是线程池,如何使用,为什么要用)

    1.什么是线程池:  java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池 多线程技术主要解决处理 ...

  4. 一篇关于cfDNA的综述

    文章题目:A Field Guide for Cancer Diagnostics using cell-free DNA: from Principles to Practice and Clini ...

  5. mysql-connector-java小笔记

    Java 连接MySQL需要驱动包,否则JDBC无法访问数据库(无法注册驱动),常用的是mysql-connector-java,在idea中新建项目时可以在选择依赖时勾选Mysql,这样就会自动加载 ...

  6. [BZOJ4566][HAOI2016]找相同子串

    COGS传送门 用SAM重新写了一遍.. 我的方法比较笨,先把两个串连在一起,算出来相同子串个数,同理算出s1和s2的子串个数.作差即可. 至于如何统计子串个数,首先toposort后搞出right集 ...

  7. [ARC061E]すぬけ君の地下鉄旅行 / Snuke's Subway Trip

    题目大意:Snuke的城镇有地铁行驶,地铁线路图包括$N$个站点和$M$个地铁线.站点被从$1$到$N$的整数所标记,每条线路被一个公司所拥有,并且每个公司用彼此不同的整数来表示. 第$i$条线路($ ...

  8. mybatis的一级缓存和二级缓存(1)

    1.mybatis一级缓存,sqlSesion级别的缓存,一级缓存默认一直开启的,sqlSession级别的一个Map,把查询的数据放到一个Map中,以后需要相同的数据,直接从Map中去取 与数据库一 ...

  9. 爬虫框架Scrapy之Downloader Middlewares

    反反爬虫相关机制 Some websites implement certain measures to prevent bots from crawling them, with varying d ...

  10. UVa 10883 超级平均数(二项式系数+对数计算)

    https://vjudge.net/problem/UVA-10883 题意: 给出n个数,每相邻两个数求平均数,依次类推,最后得到1个数,求该数. 思路: 演算一下可以发现最后各个数的系数就是二项 ...