How to earn more

My Tags   (Edit)
  Source : ww
  Time limit : 1 sec   Memory limit : 64 M

Submitted : 373, Accepted : 212

Xiao Ming is an expert in computer science and technology, so he can get a lot of projects every month. The projects always bring him a lot of money, now he is thinking how toearn money as more as possible.

Every month he can get m projects, and each project Ai will bring him Xiyuan. Although Xiao Ming is an expert, he still needs to hire someother guys to help him. Of course, the employees are not as good as Xiao Ming, for they are just good at some single aspect. So, they should work together to finish one project.There is a list shows the salary of m employees, who are labeled from 0 to m-1. Xiao Ming only hires employees, in that list, and he knows who will be needed by each project.If one employee is hired, he can join in several projects.

Input

The first line is an integer c shows the number of cases. For each case, the first line has two numbersm,n(m,n <=100), denoting that there is m projects and n employees on the list.The second line hasm integers, which are seperated by a single blank, the ith number Ximeans the project Ai will bring Xiao Ming Xiyuan.Xi is less the 10000. The third line has n integers, which are seperated by a single blank,the ith number Yimeans the employee Bi will cost Xiao Ming Yiyuan.And the next m lines will show which part of the employees will be needed by each project. Linei is a list of the employees, who are needed by project Ai.In each line, first a number Zi shows the number of employees needed by this project. And Zi labels of the emloyees follows, which are still seperated by a sigle blank.

Output

You should output a single integer shows the maximun money Xiao Ming can earn in a single month. The money he can earn is equall to the money he can totally get minus the money he totally cost. You should not leave any extra blanks at the end of each line.

Sample Input

1
3 5
30 40 43
55 17 23 22 11
3 0 1 2
3 1 2 3
2 2 1

Sample Output

21

Hint

If Xiao Ming can do less project to earn more money, he will certainly do that.

【题目大意】
有M个项目和N个员工。做项目i可以获得Ai元,但是必须雇用若干个指定的员工。雇用员工j需要花费Bj元,且一旦雇用,员工j可以参加多个项目的开发。问经过合理的项目取舍,最多能挣多少钱。(1 <= M, N <= 100)
【建模方法】
注意到题目中加粗的两个字“必须”,此题是典型的“蕴含式最大获利问题”,套用解决最大权闭合子图的建模方法即可解决。每个项目i作为一个点并连边(s, i, Ai),每名员工j作为一个点并连边(j, t, Bj),若项目i需要雇用员工j则连边(i, j, ∞)。设最小割为ans,那么ΣAi-ans即为结果。(引自《网络流建模汇总》by Edelweiss)

总结:图论的题目会wa总是因为数组范围开的不够大。

815404

  2634 2016-07-14 10:52:50 Accepted 0.00 s 3228 K C++ 2979 B ksq2013
#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;
int m,n,s,t,ecnt,first[500],nxt[100100],ans,tot;
struct Edge{int u,v,cap,flow;}e[100100];
bool vis[500];
int d[500],p[500],q[500],cur[500],num[500];
void Link(int a,int b,int c)
{
e[++ecnt].u=a,e[ecnt].v=b,e[ecnt].cap=c,e[ecnt].flow=0;
nxt[ecnt]=first[a],first[a]=ecnt;
e[++ecnt].u=b,e[ecnt].v=a,e[ecnt].cap=0,e[ecnt].flow=0;
nxt[ecnt]=first[b],first[b]=ecnt;
}
void bfs()
{
memset(vis,false,sizeof(vis));
int head=0,tail=1;
q[0]=t,d[t]=0,vis[t]=true;
while(head^tail){
int now=q[head++];
for(int i=first[now];i;i=nxt[i])
if(!vis[e[i].u]&&e[i].cap>e[i].flow){
vis[e[i].u]=true;
d[e[i].u]=d[now]+1;
q[tail++]=e[i].u;
}
}
}
int Agument()
{
int x=t,a=INF;
while(x^s){
a=min(a,e[p[x]].cap-e[p[x]].flow);
x=e[p[x]].u;
}
x=t;
while(x^s){
e[p[x]].flow+=a;
e[p[x]^1].flow-=a;
x=e[p[x]].u;
}
return a;
}
int ISAP()
{
int flow=0;
bfs();
memset(num,0,sizeof(num));
for(int i=0;i<=n+m+1;i++)num[d[i]]++;
int x=s;
for(int i=0;i<=n+m+1;i++)cur[i]=first[i];
while(d[s]<n+m+2){
if(!(x^t)){
flow+=Agument();
x=s;
}
bool advanced=false;
for(int i=cur[x];i;i=nxt[i])
if(e[i].cap>e[i].flow&&d[x]==d[e[i].v]+1){
advanced=true;
p[e[i].v]=i;
cur[x]=i;
x=e[i].v;
break;
}
if(!advanced){
int mn=m+n;
for(int i=first[x];i;i=nxt[i])
if(e[i].cap>e[i].flow)
mn=min(mn,d[e[i].v]);
if(--num[d[x]]==0)break;
num[d[x]=mn+1]++;
cur[x]=first[x];
if(x^s)x=e[p[x]].u;
}
}
return flow;
}
int main()
{
int T;
scanf("%d",&T);
for(;T;T--){
scanf("%d%d",&m,&n);
s=0,t=m+n+1,ecnt=1,ans=tot=0;
memset(first,0,sizeof(first));
memset(nxt,0,sizeof(nxt));
memset(d,0,sizeof(d));
memset(q,0,sizeof(q));
memset(p,0,sizeof(p));
for(int i=1;i<=m;i++){
int x;
scanf("%d",&x);
Link(s,i,x);
tot+=x;
}
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
Link(i+m,t,x);
}
for(int i=1;i<=m;i++){
int tmp;
scanf("%d",&tmp);
for(int x;tmp;tmp--){
scanf("%d",&x);
Link(i,x+1+m,INF);
}
}
ans=ISAP();
printf("%d\n",tot-ans);
}
return 0;
}

Hoj2634 How to earn more?的更多相关文章

  1. [HOJ2634] How to earn more 最大权闭合子图

    Xiao Ming is an expert in computer science and technology, so he can get a lot of projects every mon ...

  2. 7 Ways to earn money on programming(转)

    英文原文:7 Ways to earn money on programming 几个星期前,当我收到一个自称 Someone712 的人发给我的一条消息时,我决定要写一篇如何用编程赚钱的博客文章.S ...

  3. [LeetCode] Delete and Earn 删除与赚取

    Given an array nums of integers, you can perform operations on the array. In each operation, you pic ...

  4. [Swift]LeetCode740. 删除与获得点数 | Delete and Earn

    Given an array nums of integers, you can perform operations on the array. In each operation, you pic ...

  5. 740. Delete and Earn

    Given an array nums of integers, you can perform operations on the array. In each operation, you pic ...

  6. [LeetCode]Delete and Earn题解(动态规划)

    Delete and Earn Given an array nums of integers, you can perform operations on the array. In each op ...

  7. leetcode笔记(六)740. Delete and Earn

    题目描述 Given an array nums of integers, you can perform operations on the array. In each operation, yo ...

  8. LeetCode 740. Delete and Earn

    原题链接在这里:https://leetcode.com/problems/delete-and-earn/ 题目: Given an array nums of integers, you can ...

  9. LC 740. Delete and Earn

    Given an array nums of integers, you can perform operations on the array. In each operation, you pic ...

随机推荐

  1. Android Testing学习02 HelloTesting 项目建立与执行

    Android Testing学习02 HelloTesting 项目建立与执行 Android测试,分为待测试的项目和测试项目,这两个项目会生成两个独立的apk,但是内部,它们会共享同一个进程. 下 ...

  2. Android JNI 和 NDK

    1.Android NDK 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  3. 单独编译Android系统模块并替换进系统

    例如,我修改了frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java文件,进入frame ...

  4. 【代码笔记】iOS-判断是否是iPhone5

    一,代码. #import "RootViewController.h" // 判断是否是iPhone5 #define iPhone5 ([UIScreen instancesR ...

  5. CEF3可行性

    Chromium Embedded Framework 顾名思义,内嵌式CHROME,详细的介绍参阅 http://yogurtcat.com/posts/cef/hello-cef.html 为什么 ...

  6. 新版微耕软件(N3000)与旧版2000的实体功能区别

    更多细节请参阅其软件操作说明书. 建议:基于安全的应用始终变化不断,软件投入一直无法满足客户的定制化要求.不如提供基本的SDK,接口,允许第三方以插件的形式开发控制界面.报表. 软件只提供核心的界面. ...

  7. 10个关于Java异常的常见问题

    这篇文章总结了十个经常被问到的JAVA异常问题: 1.检查型异常VS非检查型异常 简单的说,检查型异常是指需要在方法中自己捕获异常处理或者声明抛出异常由调用者去捕获处理: 非检查型异常指那些不能解决的 ...

  8. Maven项目无法引入 Maven Dependencies Libraries 问题

    昨天在check下来maven项目之后一些配置好了,就是下载不是maven 依赖库,后面再网上找到如下解决方案. 在.classpath文件中加入如下代码就好了. <classpathentry ...

  9. C#语言基础——结构体和枚举类型

    结构体和枚举类型 一.结构体(struct) 结构类型是用户自己定义的一种类型,它是由其他类型组合而成的,可包含构造函数.常数.字段.方法.属性.索引器.运算符.事件和嵌套类型的值类型.结构在几个重要 ...

  10. 页断裂(partial write)与doublewrite技术

    mysql double write (二次写)是mysql innodb存储引擎的一个重要特性,本人这两天翻阅了相关的资料,结合自己已有的知识,说说自己对double write的理解,供各位看官参 ...