POJ2987 Firing


Description

You’ve finally got mad at “the world’s most stupid” employees of yours and decided to do some firings. You’re now simply too mad to give response to questions like “Don’t you think it is an even more stupid decision to have signed them?”, yet calm enough to consider the potential profit and loss from firing a good portion of them. While getting rid of an employee will save your wage and bonus expenditure on him, termination of a contract before expiration costs you funds for compensation. If you fire an employee, you also fire all his underlings and the underlings of his underlings and those underlings’ underlings’ underlings… An employee may serve in several departments and his (direct or indirect) underlings in one department may be his boss in another department. Is your firing plan ready now?

Input

The input starts with two integers n (0 < n ≤ 5000) and m (0 ≤ m ≤ 60000) on the same line. Next follows n + m lines. The first n lines of these give the net profit/loss from firing the i-th employee individually bi (|bi| ≤ 107, 1 ≤ i ≤ n). The remaining m lines each contain two integers i and j (1 ≤ i, j ≤ n) meaning the i-th employee has the j-th employee as his direct underling.

Output

Output two integers separated by a single space: the minimum number of employees to fire to achieve the maximum profit, and the maximum profit.

Sample Input

5 5

8

-9

-20

12

-10

1 2

2 5

1 4

3 4

4 5

Sample Output

2 2

Hint

As of the situation described by the sample input, firing employees 4 and 5 will produce a net profit of 2, which is maximum.


题意就是有一些员工,开除一个员工会得到相应的盈利或者亏损

然后员工之间有一些上司和下属的关系,如果开除一个上司必须要开除他的所有下属

最大化盈利,输出开除的员工数和盈利数

一开始不知道这是最大权闭合图,后面看到网上的介绍才了解。

那么什么是闭合图呢?

在一个图中,我们选取一些点构成集合,且集合中的点向外连出的弧所指向的终点也在集合中,则我们称这个集合为闭合图

那么最大权闭合图就是所有闭合图中权值和最大的一个

了解了概念之后,我们如何对这一类问题进行解决呢?

我们构造一个流量网络满足以下条件:

1 存在源点S和汇点T

2 对于所有权值为正的点,连接一条容量为点权,从S到这个点的边

3 对于所有权值为负的点,连接一条容量为点权相反数,从这个点到T的边

4 原图中连接两点的边,在流量网络中用容量为INF的边连接

在最大权闭合图中,有以下性质

1 最小割为简单割:割集的每条边都与S或T关联

2 最小割和S点关联的集合减去S点就是最大权闭合图

我们根据这两个性质就可以对问题进行求解了

感觉其实是到板子题


#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define N 10010
struct Edge{
LL u,v,cap,flow;
Edge(LL xu,LL xv,LL xcap,LL xflow){
u=xu;v=xv;cap=xcap;flow=xflow;
}
};
struct Dinic{
LL s,t,vis[N],d[N];
vector<Edge> E;
vector<LL> G[N];
void add(LL u,LL v,LL cap){
E.push_back(Edge(u,v,cap,0));
E.push_back(Edge(v,u,0,0));
LL m=E.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
bool BFS(){
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
queue<LL> Q;
Q.push(s);
vis[s]=1;
while(!Q.empty()){
LL u=Q.front();Q.pop();
for(LL i=0;i<G[u].size();i++){
Edge &e=E[G[u][i]];
if(!vis[e.v]&&e.cap>e.flow){
vis[e.v]=1;
d[e.v]=d[u]+1;
Q.push(e.v);
}
}
}
return vis[t];
}
LL DFS(LL u,LL a){
if(u==t||!a)return a;
LL flow=0;
for(LL i=0;i<G[u].size();i++){
Edge &e=E[G[u][i]];
if(d[e.v]!=d[u]+1)continue;
LL f=DFS(e.v,min(a,e.cap-e.flow));
e.flow+=f;
E[G[u][i]^1].flow-=f;
flow+=f;
a-=f;
if(!a)break;
}
return flow;
}
LL Maxflow(){
LL flow=0;
while(BFS())flow+=DFS(s,INF);
return flow;
}
void search(LL u){
vis[u]=1;
for(LL i=0;i<G[u].size();i++){
Edge e=E[G[u][i]];
if(e.cap-e.flow>0&&!vis[e.v])search(e.v);
}
}
}dinic;
LL n,m,p,q,sum=0;
int main(){
scanf("%lld%lld",&n,&m);
dinic.s=0;dinic.t=n+1;
for(LL i=1;i<=n;i++){
scanf("%lld",&p);
if(p>0)dinic.add(0,i,p),sum+=p;
else dinic.add(i,n+1,-p);
}
for(LL i=1;i<=m;i++){
scanf("%lld%lld",&p,&q);
dinic.add(p,q,INF);
}
LL ans1=0,ans2=sum-dinic.Maxflow();
memset(dinic.vis,0,sizeof(dinic.vis));
dinic.search(dinic.s);
for(LL i=1;i<=n;i++)ans1+=dinic.vis[i];
printf("%lld %lld",ans1,ans2);
return 0;
}

POJ2987 Firing 【最大权闭合图】的更多相关文章

  1. POJ2987 Firing 最大权闭合图

    详情请参考http://www.cnblogs.com/kane0526/archive/2013/04/05/3001557.html 值得注意的地方,割边会把图分成两部分,一部分和起点相连,另一部 ...

  2. poj2987 Firing 最大权闭合子图 边权有正有负

    /** 题目:poj2987 Firing 最大权闭合子图 边权有正有负 链接:http://poj.org/problem?id=2987 题意:由于金融危机,公司要裁员,如果裁了员工x,那么x的下 ...

  3. poj 2987 Firing 最大权闭合图

    题目链接:http://poj.org/problem?id=2987 You’ve finally got mad at “the world’s most stupid” employees of ...

  4. POJ 2987 Firing(最大流最小割の最大权闭合图)

    Description You’ve finally got mad at “the world’s most stupid” employees of yours and decided to do ...

  5. POJ 2987:Firing(最大权闭合图)

    http://poj.org/problem?id=2987 题意:有公司要裁员,每裁一个人可以得到收益(有正有负),而且如果裁掉的这个人有党羽的话,必须将这个人的所有党羽都裁除,问最少的裁员人数是多 ...

  6. POJ 2987 Firing【最大权闭合图-最小割】

    题意:给出一个有向图,选择一个点,则要选择它的可以到达的所有节点.选择每个点有各自的利益或损失.求最大化的利益,以及此时选择人数的最小值. 算法:构造源点s汇点t,从s到每个正数点建边,容量为利益.每 ...

  7. POJ 2987 Firing 网络流 最大权闭合图

    http://poj.org/problem?id=2987 https://blog.csdn.net/u014686462/article/details/48533253 给一个闭合图,要求输出 ...

  8. POJ 2987 Firing(最大权闭合图)

    [题目链接] http://poj.org/problem?id=2987 [题目大意] 为了使得公司效率最高,因此需要进行裁员, 裁去不同的人员有不同的效率提升效果,当然也有可能是负的效果, 如果裁 ...

  9. poj 2987 最大权闭合图

    Language: Default Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 8744   Accept ...

随机推荐

  1. 【Linux】无法添加用户,报“useradd: cannot open /etc/passwd”问题解决过程记录

    问题描述 今天在一个新的Linux环境添加用户的时候,发现不能添加,遇到了以下错误 useradd: cannot open /etc/passwd 解决方法 用lsattr命令查看/etc/pass ...

  2. Mysql存储过程、索引

    sql语句执行顺序: from--->where--->group by--->having--->计算所有的表达式--->order by--->select 输 ...

  3. 二十二 Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy模拟登陆和知乎倒立文字验证码识别

    第一步.首先下载,大神者也的倒立文字验证码识别程序 下载地址:https://github.com/muchrooms/zheye 注意:此程序依赖以下模块包 Keras==2.0.1 Pillow= ...

  4. Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache

    1.事件描述:CentOS7下使用tree命令,发现该命令没有被安装,在安装的过程中发现yum报错 1 2 3 4 5 [root@openstack-01 ~]# tree -d bash: tre ...

  5. POJ-3659-最小支配集裸题/树形dp

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7127   Accepted: 254 ...

  6. 河南省多校联盟二-A

    1279: 简单的背包问题 时间限制: 1 秒  内存限制: 32 MB提交: 361  解决: 20 题目描述 相信大家都学过背包问题了吧,那么现在我就考大家一个问题.有n个物品,每个物品有它的重量 ...

  7. nyoj42——连通图加欧拉(连通图板子)dfs

    一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下 ...

  8. linux-Centos7安装mysql5.7.19

    1.下载mysql 网址: https://dev.mysql.com/downloads/mysql/ 2.选择源码包,通用版点击下载 直接下载就可以了,不用登录 3.解压编译 先安装相关依赖包 y ...

  9. 卸载Linux自带的JDK

    Redhat Enterprise Linux中自带了jdk的旧版本,往往需要卸载,卸载步骤如下: 在终端输入:yum remove java 终端显示:Is this ok[y/N]: 输入y,按回 ...

  10. 【Python】测算代码运行时间

    整理自这里和这里 timeit模块 timeit模块定义了接受两个参数的 Timer 类.两个参数都是字符串. 第一个参数是你要计时的语句或者函数. 传递给 Timer 的第二个参数是为第一个参数语句 ...