poj 2987 Firing 最大权闭合图
题目链接:http://poj.org/problem?id=2987
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?
题目描述:公司解雇员工,每个员工有一个权值,可正可负可为零(对公司而言等同于员工对公司的贡献力)。然后给出一些员工上下级的关系,如果解雇一个员工(比如经理主管之类的),那么他手下的员工都会被解雇,问对公司获利最大的解雇计划以及解雇员工人数。
算法分析:每个员工看作一个点,新增源点from和汇点to,from连边权值为正的点,边权为该权值;to连边权值为负的点,边权为权值的绝对值;员工之间的上下级也连边,边权为无穷大。最后最大权闭合图=权值为正的点的权值的和-最小割。
最大权闭合图参考资料:
大牛博客:【网络流】最大权闭合图
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 0x7fffffff
using namespace std;
typedef long long LL;
const int maxn=+;
const int M = +; int n,m,from,to;
struct node
{
int v,flow;
int next;
}edge[M*];
int head[maxn],edgenum; void add(int u,int v,int flow)
{
edge[edgenum].v=v ;edge[edgenum].flow=flow ;
edge[edgenum].next=head[u] ;head[u]=edgenum++ ; edge[edgenum].v=u ;edge[edgenum].flow= ;
edge[edgenum].next=head[v] ;head[v]=edgenum++ ;
} int d[maxn];
int bfs()
{
memset(d,,sizeof(d));
d[from]=;
queue<int> Q;
Q.push(from);
while (!Q.empty())
{
int u=Q.front() ;Q.pop() ;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].v;
if (!d[v] && edge[i].flow)
{
d[v]=d[u]+;
Q.push(v);
if (v==to) return ;
}
}
}
return ;
} int dfs(int u,int flow)
{
if (u==to || flow==) return flow;
int cap=flow;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].v;
if (d[v]==d[u]+ && edge[i].flow)
{
int x=dfs(v,min(edge[i].flow,cap));
edge[i].flow -= x;
edge[i^].flow += x;
cap -= x;
if (cap==) return flow;
}
}
return flow-cap;
} LL dinic()
{
LL ans=;
while (bfs()) ans += dfs(from,inf);
return ans;
} int vis[maxn];
void dfs2(int u)
{
if (u==to) return ;
vis[u]=;
for (int i=head[u] ;i!=- ;i=edge[i].next)
if (edge[i].flow> && !vis[edge[i].v ])
dfs2(edge[i].v);
} int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-,sizeof(head));
edgenum=;
from=n+;
to=from+;
int a,b;
LL sum=;
for (int i= ;i<=n ;i++)
{
scanf("%d",&a);
if (a>) {sum += a ;add(from,i,a) ;}
else add(i,to,-a);
}
for (int i= ;i<m ;i++)
{
scanf("%d%d",&a,&b);
add(a,b,inf);
}
sum=sum-dinic();
memset(vis,,sizeof(vis));
dfs2(from);
int ans=;
for (int i= ;i<=n ;i++) if (vis[i]) ans++;
printf("%d %I64d\n",ans,sum);
}
return ;
}
poj 2987 Firing 最大权闭合图的更多相关文章
- POJ 2987 - Firing - [最大权闭合子图]
题目链接:http://poj.org/problem?id=2987 Time Limit: 5000MS Memory Limit: 131072K Description You’ve fina ...
- POJ 2987 Firing | 最大权闭合团
一个点带权的图,有一些指向关系,删掉一个点他指向的点也不能留下,问子图最大权值 题解: 这是最大权闭合团问题 闭合团:集合内所有点出边指向的点都在集合内 构图方法 1.S到权值为正的点,容量为权值 2 ...
- POJ2987 Firing 最大权闭合图
详情请参考http://www.cnblogs.com/kane0526/archive/2013/04/05/3001557.html 值得注意的地方,割边会把图分成两部分,一部分和起点相连,另一部 ...
- POJ 2987:Firing(最大权闭合图)
http://poj.org/problem?id=2987 题意:有公司要裁员,每裁一个人可以得到收益(有正有负),而且如果裁掉的这个人有党羽的话,必须将这个人的所有党羽都裁除,问最少的裁员人数是多 ...
- POJ 2987 Firing 网络流 最大权闭合图
http://poj.org/problem?id=2987 https://blog.csdn.net/u014686462/article/details/48533253 给一个闭合图,要求输出 ...
- POJ 2987 Firing(最大权闭合图)
[题目链接] http://poj.org/problem?id=2987 [题目大意] 为了使得公司效率最高,因此需要进行裁员, 裁去不同的人员有不同的效率提升效果,当然也有可能是负的效果, 如果裁 ...
- POJ 2987 Firing(最大流最小割の最大权闭合图)
Description You’ve finally got mad at “the world’s most stupid” employees of yours and decided to do ...
- POJ 2987 Firing【最大权闭合图-最小割】
题意:给出一个有向图,选择一个点,则要选择它的可以到达的所有节点.选择每个点有各自的利益或损失.求最大化的利益,以及此时选择人数的最小值. 算法:构造源点s汇点t,从s到每个正数点建边,容量为利益.每 ...
- poj 2987(最大权闭合图+割边最少)
题目链接:http://poj.org/problem?id=2987 思路:标准的最大权闭合图,构图:从源点s向每个正收益点连边,容量为收益:从每个负收益点向汇点t连边,容量为收益的相反数:对于i是 ...
随机推荐
- .net框架
转载:http://www.cnblogs.com/JimmyZhang/archive/2012/11/27/2790759.html 本书是一本讲解.NET技术的书籍,目标读者群也是在.NET框架 ...
- canvas 绘制矩形和圆形
canvas绘制有两神方法:1).填充(fill)填充是将图形内部填满. 2).绘制边框 (stroke)绘制边框是不把图形内部填满,只是绘制图形的外框. 当我们在绘制图形的时候,首先要设定好绘制的样 ...
- [译]Memory Reordering Caught in the Act
原文:http://preshing.com/20120515/memory-reordering-caught-in-the-act/ 编写lock-free的C/C++程序时,在保证memory ...
- linux基本使用(一)
分区1./ 根分区2. swap 交换分区(大小建议是内存的1~2倍)3. /home 分区4./boot 引导文件(启动加载)分区5./var 等,最低 要有前2个分区吧,最好有home分区,因为没 ...
- SAE平台的文件I/O处理
用过SAE平台的朋友应该知道,出于平台安全性的考虑,SAE限制了用户对于本地IO的使用.但这样对于一些传统的PHP项目,也许带来了很多不便,因为它们都或多或少的有对本地IO的操作,像Sma ...
- 【译】Spark官方文档——Spark Configuration(Spark配置)
注重版权,尊重他人劳动 转帖注明原文地址:http://www.cnblogs.com/vincent-hv/p/3316502.html Spark主要提供三种位置配置系统: 环境变量:用来启动 ...
- OC学习-1
编译和编写代码. 1. 创建代码文件夹 mkdir lession2 2. 新建类文件 touch lession2.m 3. 打开编写代码,(会用xcode打开) open lession2.m 4 ...
- Python自然语言工具包(NLTK)入门
在本期文章中,小生向您介绍了自然语言工具包(Natural Language Toolkit),它是一个将学术语言技术应用于文本数据集的 Python 库.称为“文本处理”的程序设计是其基本功能:更深 ...
- 17.python自定义函数
什么是函数,函数说白了就是将一系列代码封装起来,实现代码的重用. 什么是代码重用? 假设我有这样的需求: 但是我还是觉得太麻烦了,每次想吃饭的时候都要重复这样的步骤.此时,我希望有这样的机器:
- 【PHP】PHP中的类与对象
面向对象并不是PHP的关键,但PHP确实能很好的支持面向对象编程,而且类与对象也成为了PHP5的核心组成部分.PHP的面向对象特性让构建大型的复制应用成为可能,有了类与对象,就自然产生了各种编程范式和 ...