ZOJ 2601 Warehouse Keeper
Warehouse Keeper
This problem will be judged on ZJU. Original ID: 2601
64-bit integer IO format: %lld Java class name: Main
The company where Jerry works owns a number of warehouses that can be used to store various goods. For each warehouse the types of goods that can be stored in this warehouse are known. To avoid problems with taxes, each warehouse must store only one type of goods, and each type of goods must be stored in at most one warehouse.
Jerry is planning to receive a new lot of goods in a couple of days and he must store the goods in the warehouses. However there are some goods in some warehouses already and Jerry wants to move as few of them as possible.
Help him to find the maximal number of types of goods that he can store in the warehouses and the minimal number of goods he must move in order to do that.
Input
The input contains multiple test cases. The first line of the input is a single integer T (1 <= T <= 40) which is the number of test cases. T test cases follow, each preceded by a single blank line.
The first line of each test case contains integer numbers m and n (2 <= m, n <= 200) - the number of warehouses and the number of types of goods respectively.
The following m lines describe warehouses. Each line contains ki - the number of various types of goods that can be stored in this warehouse (remember, only one type of goods can be stored in a warehouse at a time), followed by ki integer numbers - the types of goods that can be stored.
The last line contains m integer numbers - for each warehouse either 0 is provided if there is no goods in this warehouse, or the type of goods that is currently stored in this warehouse if there is one. It is guaranteed that the initial configuration is correct, that is, each warehouse stores the goods it can store, and no type of goods is stored in more than one warehouse.
Output
For each case, on the first line print p - the maximal number of types of goods that can be stored in the warehouses, and q - the minimal number of goods that need to be moved in order to do that. After that output m integer numbers - for each warehouse output the type of goods that must be stored in this warehouse, or 0 if none must be.
Remember that you may only move goods that are already stored in some houses to other ones, you are not allowed to dispose them.
Two consecutive cases should be separated by a single blank line. No blank line should be produced after the last test case.
Sample Input
2 4 5
3 1 2 3
2 1 2
2 1 2
3 1 4 5
0 2 0 1 2 2
1 1
1 2
0 0
Sample Output
4 1
3 2 1 4 2 0
1 2
Source
Author
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <cstdlib>
#include <string>
#include <set>
#include <stack>
#define LL long long
#define INF 0x3f3f3f3f
#define pii pair<int,int>
using namespace std;
const int maxn = ;
struct arc{
int to,flow,cost,next;
arc(int x = ,int y = ,int z = ,int nxt = -){
to = x;
flow = y;
cost = z;
next = nxt;
}
};
arc e[maxn*maxn];
int head[maxn],d[maxn],p[maxn],house[maxn];
int tot,S,T,n,m;
bool in[maxn];
int vis[maxn];
vector<int>g[maxn];
void add(int u,int v,int flow,int cost){
e[tot] = arc(v,flow,cost,head[u]);
head[u] = tot++;
e[tot] = arc(u,,-cost,head[v]);
head[v] = tot++;
}
bool spfa(){
queue<int>q;
for(int i = S; i <= T; ++i){
d[i] = INF;
in[i] = false;
p[i] = -;
}
d[S] = ;
q.push(S);
while(!q.empty()){
int u = q.front();
q.pop();
in[u] = false;
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].flow && d[e[i].to] > d[u] + e[i].cost){
d[e[i].to] = d[u] + e[i].cost;
p[e[i].to] = i;
if(!in[e[i].to]){
in[e[i].to] = true;
q.push(e[i].to);
}
}
}
}
return p[T] > -;
}
int solve(int &cost){
int flow = cost = ;
while(spfa()){
int minF = INF;
for(int i = p[T]; ~i; i = p[e[i^].to])
minF = min(minF,e[i].flow);
for(int i = p[T]; ~i; i = p[e[i^].to]){
e[i].flow -= minF;
e[i^].flow += minF;
}
cost += minF*d[T];
flow += minF;
}
return flow;
}
int main(){
int cs,u;
scanf("%d",&cs);
bool cao = false;
while(cs--){
if(cao) puts("");
cao = true;
memset(head,-,sizeof(head));
memset(house,,sizeof(house));
memset(vis,,sizeof(vis));
scanf("%d %d",&m,&n);
S = tot = ;
T = n + m + ;
for(int i = ; i <= T; ++i) g[i].clear();
for(int i = ; i <= m; ++i){
int tmp = ;
scanf("%d",&tmp);
while(tmp--){
scanf("%d",&u);
g[i].push_back(u);
}
}
for(int i = ; i <= m; ++i){
scanf("%d",house+i);
vis[house[i]] = i;
}
for(int i = ; i <= m; ++i){
for(int j = g[i].size()-; j >= ; --j){
int tmp = g[i][j];
if(vis[tmp] == i) add(i,tmp+m,,);
else if(vis[tmp] && vis[tmp] != i) add(i,tmp+m,,);
else add(i,tmp+m,,);
}
}
for(int i = ; i <= m; ++i)
add(S,i,,);
for(int i = ; i <= n; ++i)
add(i+m,T,,vis[i]?-:);
int ans,cost;
ans = solve(cost);
int ahouse[maxn],mb = ;
memset(ahouse,,sizeof(ahouse));
for(int i = ; i < tot; i += ){
if(e[i].to == T || e[i^].to == S ) continue;
if(e[i].flow == ) ahouse[e[i^].to] = e[i].to-m;//cout<<e[i^1].to<<" "<<e[i].to-m<<endl;
}
for(int i = ; i <= m; ++i)
if(house[i] && ahouse[i] != house[i]) mb++;
printf("%d %d\n",ans,mb);
for(int i = ; i <= m; ++i)
printf("%d%c",ahouse[i],i == m ?'\n':' ');
}
return ;
}
ZOJ 2601 Warehouse Keeper的更多相关文章
- 2013ACM/ICPC亚洲区南京站现场赛---Poor Warehouse Keeper(贪心)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4803 Problem Description Jenny is a warehouse keeper. ...
- Poor Warehouse Keeper
Poor Warehouse Keeper http://acm.hdu.edu.cn/showproblem.php?pid=4803 Jenny is a warehouse keeper. He ...
- hdu 4803 Poor Warehouse Keeper(贪心+数学)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u011328934/article/details/26005267 题目链接:hdu 4803 P ...
- HDU 4803 Poor Warehouse Keeper (贪心+避开精度)
555555,能避开精度还是避开精度吧,,,,我们是弱菜.. Poor Warehouse Keeper Time Limit: 2000/1000 MS (Java/Others) Memor ...
- HDU 4803 Poor Warehouse Keeper
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4803 解题报告:有一个记录器,一共有两个按钮,还有两行屏幕显示,第一行的屏幕显示的是数目,第二行的屏幕 ...
- HDU4803_Poor Warehouse Keeper
题目很有意思,我想说其实我在比赛的时候就看过了一下这个题目,今天才这么快搞出来吧. 其实总共按上键的次数不会超过10个,我们可以每次假设相隔按两次上键之间按了xi次下键,由于上键的次数是确定的,所以最 ...
- 【贪心】hdu4803 Poor Warehouse Keeper
题意:一开始有1个物品,总价是1.你的一次操作可以要么使得物品数量+1,总价加上当前物品的单价.要么可以使得总价+1,物品数量不变.问你最少要几次操作从初始状态到达有x个物品,总价是y的状态.这里的y ...
- HDU 4803 Poor Warehouse Keeper(贪心)
题目链接 题意 :屏幕可以显示两个值,一个是数量x,一个是总价y.有两种操作,一种是加一次总价,变成x,1+y:一种是加一个数量,这要的话总价也会相应加上一个的价钱,变成x+1,y+y/x.总价显示的 ...
- HDU - 4803 - Poor Warehouse Keeper (思维)
题意: 给出x,y两个值分别代表x个物品,总价为y 有两种变化: 1.使总价+1,数量不变 2.数量+1,总价跟着变化 (y = y + y / x) 思路: 给出目标x,y,计算最少变化次使数量变化 ...
随机推荐
- No content type provided for validation of a content model---WebLogic问题
一个web项目,复制到Weblogic domain下的autodeploy目录下,可是从BEA管理控制台中的Deployments下却找不到该项目,奇怪了,这个以前拷过来就可以用的啊?! 查看控制台 ...
- VUE使用中踩过的坑
前言 vue如今可谓是一匹黑马,github star数已居第一位!前端开发对于vue的使用已经越来越多,它的优点就不做介绍了,本篇是我对vue使用过程中以及对一些社区朋友提问我的问题中做的一些总结, ...
- 2019-03-15 使用Request POST获取CNABS网站上JSON格式的表格数据,并解析出来用xlwt写到Excel中
import requests import xlwt url = 'https://v1.cn-abs.com/ajax/ChartMarketHandler.ashx' headers={ 'Us ...
- How-to-quick-getting-started-for-Frontend
一转眼已一年多不专注前端方面的开发工作,这一年前端方面的技术又是新天地,偶然接到内部团队邀请我给他们做一个前端的讲座,希望能帮助他们快速.且深刻了解前端这个行业以及行业内的知识,这可真有点让我为难,由 ...
- 机器学习关于AUC的理解整理
AUC 几何意义:ROC曲线与X轴的面积 https://blog.csdn.net/luo3300612/article/details/80367901 AUC物理意义:随机给定一个正样本和一个负 ...
- windows部署iBase4J
所需环境:jdk 1.8.eclipse(myeclipse不可以).nginx.activeMQ .zookeeper.redis 第一步 下载jdk1.8 按步骤安装至指定位置即可 第二步 安装e ...
- (转)redis源代码分析 – event library
每个cs程序尤其是高并发的网络服务端程序都有自己的网络异步事件处理库,redis不例外. 事件库仅仅包括ae.c.ae.h,还有3个不同的多路复用(本文仅描述epoll)的wrapper文件,事件库封 ...
- Ubuntu PostgreSql主从切换
主机:192.168.100.70 从机:192.168.100.71 通用配置(即主从都要配置) 修改/etc/postgresql/10/main/pg_hba.conf host all all ...
- linux下线程
linux下线程 线程与进程的关系: 之前转载的微信文章,进程与线程的差别已经说得比較清楚了.能够查看之前转载的文章.linux进程与线程的差别. 创建一个线程: #include<pthrea ...
- html屏蔽鼠标右键
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...