POJ 2987:Firing(最大权闭合图)
http://poj.org/problem?id=2987
题意:有公司要裁员,每裁一个人可以得到收益(有正有负),而且如果裁掉的这个人有党羽的话,必须将这个人的所有党羽都裁除,问最少的裁员人数是多少和最大收益是多少。
思路:有依赖关系,最大权闭合图。我们要得到最大收益,那么就是尽量选择更多收益为正数的人,选择更少收益为负数的人,因此我们将收益为正数的人与源点连一条边,将收益为负数的人与汇点连一条边,这样得到的割集就是未选择的收益为正数的人+选择的收益为负数的人(也可以是损失的收益),很明显答案要使这个割集越小越好,那么就是求最小割。我们能够得到的最大收益是所有正数的和sum,我们再用sum-最小割(损失的收益)就可以得到最大收益了。
至于最少的裁员人数,我也挺迷糊的。看到别人的“将从S出发能到达的点看做firing的集合中的点,其他的能到T的点看作不被firing的集合中的点,那么在做完最大流之后自然就不会有firing集合中的点指向不被firing的集合中的点的边了,否则就会形成增广路。”这句话后,似乎我们只要在最终的残余网络中,只要能从S遍历到的点,就可以看成是被裁掉的点,因为最终肯定会遇到割边达不到T,所以我们直接DFS残余网络的点数就可以得到最少的裁员人数了。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define N 5010
#define INF 0x3f3f3f3f
typedef long long LL;
struct Edge {
int v, nxt, cap;
} edge[];
int head[N], cur[N], dis[N], pre[N], gap[N], vis[N], S, T, tot; void Add(int u, int v, int cap) {
edge[tot] = (Edge) {v, head[u], cap}; head[u] = tot++;
edge[tot] = (Edge) {u, head[v], }; head[v] = tot++;
} int BFS() {
memset(dis, INF, sizeof(dis));
memset(gap, , sizeof(gap));
queue<int> que; que.push(T);
dis[T] = ; gap[]++;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(dis[v] < INF) continue;
dis[v] = dis[u] + ;
gap[dis[v]]++;
que.push(v);
}
}
} LL ISAP(int n) {
BFS();
memcpy(cur, head, sizeof(cur));
int u = pre[S] = S, i, flow, index; LL ans = ;
while(dis[S] < n) {
if(u == T) {
flow = INF;
for(i = S; i != T; i = edge[cur[i]].v)
if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
for(i = S; i != T; i = edge[cur[i]].v)
edge[cur[i]].cap -= flow, edge[cur[i]^].cap += flow;
u = index; ans += flow;
}
for(i = cur[u]; ~i; i = edge[i].nxt) if(edge[i].cap > && dis[edge[i].v] + == dis[u]) break;
if(~i) {
cur[u] = i; pre[edge[i].v] = u; u = edge[i].v;
} else {
int md = n + ;
if(--gap[dis[u]] == ) break;
for(i = head[u]; ~i; i = edge[i].nxt)
if(edge[i].cap > && dis[edge[i].v] < md) md = dis[edge[i].v], cur[u] = i;
gap[dis[u] = md + ]++;
u = pre[u];
}
}
return ans;
} int DFS(int u) {
vis[u] = ; int ans = ;
for(int i = head[u]; ~i; i = edge[i].nxt)
if(edge[i].cap > && !vis[edge[i].v]) ans += DFS(edge[i].v);
return ans;
} int main() {
int n, m;
while(~scanf("%d%d", &n, &m)) {
S = , T = n + ;
LL sum = ; int u, v; tot = ;
memset(head, -, sizeof(head));
memset(vis, , sizeof(vis));
for(int i = ; i <= n; i++) {
int w; scanf("%d", &w);
if(w > ) Add(S, i, w), sum += w;
else Add(i, T, -w);
}
for(int i = ; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
Add(u, v, INF);
}
LL ans = ISAP(T + );
int res = DFS(S);
printf("%d %lld\n", --res, sum - ans);
}
return ;
}
POJ 2987:Firing(最大权闭合图)的更多相关文章
- poj 2987 Firing 最大权闭合图
题目链接:http://poj.org/problem?id=2987 You’ve finally got mad at “the world’s most stupid” employees of ...
- 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 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是 ...
随机推荐
- springboot使用logback日志,部署到tomcat不生效问题解决
1.springboot 配置日志方法 使用该方法配置日志,在本地调试可以正常写入日志文件,但是打包发布到tomcat以后日志配置不生效. 2.修改配置 Spring Boot官方推荐优先使用带有-s ...
- js动态创建表格
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- NoSQL Manager for MongoDB 4.6.0.3 带key
NoSQL Manager for MongoDB 4.6.0.3 是一个Windows平台的MongoDB高级管理工具.请低调使用. 博客园文件一次最大不超过10M. 官方安装包: mongodbm ...
- jquery 可以给事件传参数
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Boost的某些库还是需要生成二进制的库的,必须安装才行,以及使用库的方法
头文件就是库使用者最常问的问题就是“我该怎么安装Boost”,这个也是我一开始最关心的问题,Boost这点做的很好,将大部分实现都封装在头文件里,所以对于一些基本的Boost库,其实是不需要安装的,只 ...
- Thinkphp模板开放给第三方编辑权限时,如何禁止模板使用php代码
首先我要吐槽一个问题:为什么在博客园发布的文章总是被其他网站采集过去,而他们采集过去后,排名比博客园还好,比如这篇文章,我把标题复制到百度搜索,结果第一页的搜索结果全部都是采集我的,而我在博客园发布的 ...
- github网页
GitHub主页 创建仓库 想必大家都有自己的Github账号吧,没有的可以到GitHub官网注册账号,注册完后,我们来下一步,在我们的GitHub上面右上角的New repository来创建一个仓 ...
- 将QuickReport报表保存为图片(使用TMetaFile和TMetafileCanvas)
//将报表第iPageNo页存为BMP文件 procedure ReportSaveToBMPFile(sFileName :string; iPageNo :integer) ...
- uwp 获取系统字体库
原文:uwp 获取系统字体库 效果图: 要获取到字体库首先要在 NuGet 添加 SharpDx.Direct2D1 api: /// <summary> /// 获取系统字体库列表 / ...
- iOS学习总结之ARC和非ARC的单例模式实现
iOS单例模式的实现 首先我们要明白下面三个问题: 什么是单例模式 单例模式的优点 如何实现单例模式 1.什么是单例模式 单例模式(Singleton):单例模式确保对于一个给定的类只有一个实例存在, ...