题目

Source

http://acm.hdu.edu.cn/showproblem.php?pid=5855

Description

The city planners plan to build N plants in the city which has M shops.

Each shop needs products from some plants to make profit of proi units.

Building ith plant needs investment of payi units and it takes ti days.

Two or more plants can be built simultaneously, so that the time for building multiple plants is maximum of their periods(ti).

You should make a plan to make profit of at least L units in the shortest period.

Input

First line contains T, a number of test cases.

For each test case, there are three integers N, M, L described above.

And there are N lines and each line contains two integers payi, ti(1<= i <= N).

Last there are M lines and for each line, first integer is proi, and there is an integer k and next k integers are index of plants which can produce material to make profit for the shop.

1 <= T <= 30
1 <= N, M <= 200
1≤L,ti≤1000000000
1≤payi,proi≤30000

Output

For each test case, first line contains a line “Case #x: t p”, x is the number of the case, t is the shortest period and p is maximum profit in t hours. You should minimize t first and then maximize p.

If this plan is impossible, you should print “Case #x: impossible”

Sample Input

2

1 1 2
1 5
3 1 1

1 1 3
1 5
3 1 1

Sample Output

Case #1: 5 2
Case #2: impossible

分析

题目大概说有n个工厂,建各个工厂分别要payi的花费和ti的时间,可以同时建工厂。此外还有m个商店,如果各个商店所需要k间工厂都建了,那么就得到proi的收益。现在希望收益大于等于l,问在建工厂所花时间最少的前提下,能获得的最大收益是多少。

二分时间,判定最大收益能否大于等于l;而求最大收益,这就是典型的最大权闭合子图的模型了,最小割求解即可。

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 444
#define MAXM 444*888 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-1,sizeof(level));
memset(gap,0,sizeof(gap));
level[vt]=0;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-1) continue;
level[v]=level[u]+1;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-1,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=0,aug=INF;
gap[0]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^1].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==0) break;
level[u]=minlevel+1;
gap[level[u]]++;
u=pre[u];
}
return flow;
} int n,m,l;
int pay[222],time[222],pro[222];
vector<int> need[222]; int isok(int t){
vs=0; vt=n+m+1; NV=vt+1; NE=0;
memset(head,-1,sizeof(head));
int totpro=0;
for(int i=1; i<=n; ++i){
if(time[i]<=t) addEdge(i+m,vt,pay[i]);
}
for(int i=1; i<=m; ++i){
bool flag=1;
for(int j=0; j<need[i].size(); ++j){
if(time[need[i][j]]>t){
flag=0;
break;
}
}
if(flag==0) continue;
addEdge(vs,i,pro[i]);
totpro+=pro[i];
for(int j=0; j<need[i].size(); ++j){
addEdge(i,need[i][j]+m,INF);
}
}
int res=totpro-ISAP();
if(res>=l) return res;
return -1;
} int main(){
int t;
scanf("%d",&t);
for(int cse=1; cse<=t; ++cse){
scanf("%d%d%d",&n,&m,&l);
for(int i=1; i<=n; ++i){
scanf("%d%d",&pay[i],&time[i]);
}
for(int i=1; i<=m; ++i) need[i].clear();
for(int i=1; i<=m; ++i){
int a,b;
scanf("%d%d",&pro[i],&a);
for(int j=0; j<a; ++j){
scanf("%d",&b);
need[i].push_back(b);
}
}
int l=0,r=1000000001;
while(l<r){
int mid=l+r>>1;
if(isok(mid)!=-1) r=mid;
else l=mid+1;
}
printf("Case #%d: ",cse);
if(l==1000000001){
puts("impossible");
continue;
}
printf("%d %d\n",l,isok(l));
}
return 0;
}

HDU5855 Less Time, More profit(最大权闭合子图)的更多相关文章

  1. HDU 5855 Less Time, More profit 最大权闭合子图

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5855 Less Time, More profit Time Limit: 2000/1000 MS ...

  2. Less Time, More profit 最大权闭合子图(最大流最小割)

    The city planners plan to build N plants in the city which has M shops. Each shop needs products fro ...

  3. 2018.11.06 NOIP训练 最大获利(profit)(01分数规划+最大权闭合子图)

    传送门 好题啊. ∑i<jpi,jK∗(200−K)>X\frac{\sum_{i<j}p_{i,j}}{K*(200-K)}>XK∗(200−K)∑i<j​pi,j​​ ...

  4. HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4971 Description There's a company with several ...

  5. 【POJ 2987】Firing (最小割-最大权闭合子图)

    裁员 [问题描述] 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误.给出每个人的贡献值和 ...

  6. 2018.06.27Firing(最大权闭合子图)

    Firing Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 11558 Accepted: 3494 Description ...

  7. POJ 2987 - Firing - [最大权闭合子图]

    题目链接:http://poj.org/problem?id=2987 Time Limit: 5000MS Memory Limit: 131072K Description You’ve fina ...

  8. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  9. HDU 3879 Base Station(最大权闭合子图)

    经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...

随机推荐

  1. October 1st 2016 Week 40th Saturday

    Autumn, the year's last, loveliest smile. 秋,四季流转中的最后一抹,也是最美的那一抹微笑. I love autumn because it is the h ...

  2. 高校排名 加强版(codevs 2799)

    题目描述 Description 大学排名现在已经非常流行.在网上搜索可查到关于中国大学排行的各个方面的消息. 我们知道,在一大学里通常都由许多不同的"系"(专业)组成,比如计算机 ...

  3. String[] a = new String[]{"1","2"},我如果想增加一个"3"到a中,如何增加?

    在java中数组是定长的,当你声明了数组的大小后数组的长度就不能改变在你的程序中,数组的初始化大小为2,a[0]="1";a[1]="2",所以无法产生元素a[ ...

  4. Mac系统下使用VirtualBox虚拟机安装win7--第三步 在虚拟机上安装 Windows 7

    第三步 在虚拟机上安装 Windows 7 等待虚拟机进入 Windows 7 的安装界面以后,在语言,货币,键盘输入法这一面,建议保持默认设置,直接点击“下一步”按钮,如图所示

  5. 2016"百度之星" - 初赛(Astar Round2A)All X(数学 矩阵)

    All X  Accepts: 1281  Submissions: 7580  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 65536 ...

  6. Java获取当前时间年月日、时间格式化打印、字符串转日期

    package com.sysc.simple; import java.text.ParseException; import java.text.SimpleDateFormat; import ...

  7. TortoiseSVN常用批处理命令 分类: C# 2014-08-09 11:31 648人阅读 评论(1) 收藏

    TortoiseSVN作为源代码管理软件,估计用过的都会说好,在Windows下,配合批处理命令,往往可以事半功倍,整理了下常用的批处理命令: (将下面的内容修改后,保存为*.bat文件执行即可) : ...

  8. Win10 启动模拟器

    不知道怎么解决 答:去bios里设置了.开启了虚拟化hyper,重启.

  9. windows7下安装php的imagick和imagemagick扩展教程

    这篇文章主要介绍了windows7下安装php的imagick和imagemagick扩展教程,同样也适应XP操作系统,Win8下就没测试过了,需要的朋友可以参考下 最近的PHP项目中,需要用到切图和 ...

  10. bzoj 1415 期望+记忆化搜索 ****

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdkAAAIfCAIAAACzfDFhAAAgAElEQVR4nOy9bVwTW57vm5fnhed+Pn