1. 裁员
  2. 【问题描述】
  3. 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误。给出每个人的贡献值和从属关系,求在最大贡献值的前提下最小剩下多少人及最大贡献值。留下多少人无所谓,现在老板想知道留下的人最大的贡献值是多少。
  4. 【输入描述】
  5. 第一行两个整数n,m,表示有多少个员工与多少个从属关系。
  6. 第二行n个整数,表示每个员工的贡献值。
  7. 接着m行,每行两个数x,y,表示xy的下属,一个员工可能有多个下属但不会有多个上司
  8. 【输出描述】
  9. 包括两个数,表示最大贡献值前提下最小剩下多少人及最大贡献值和。
  10. 【其他说明】:
  11. 0 < n 5000
  12. 0 m 60000
  13. 员工价值≤107
  14. 样例中留下4,5号员工是最好情况

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 ≤ ij ≤ 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

  1. 5 5
  2. 8
  3. -9
  4. -20
  5. 12
  6. -10
  7. 1 2
  8. 2 5
  9. 1 4
  10. 3 4
  11. 4 5

Sample Output

  1. 2 2
  1.  

【分析】

  最大权闭合子图。

  假设每个正权的人都留着,然后求最少要减掉多少(即还裁掉多少正权的人,雇佣多少负权的人才能满足情况)

  所以 对于w[i]>0的i add(st,i,w[i])

     对于w[i]|<0 的i add(i,ed,-w[i])

  原图 x->y add(s,y,INF)

  然后求最小割。

  但是这题要最大流的情况下,点数最小。这个 不是 很懂 明天再说吧= =

  我看别人是dfs的,然后我也dfs了。

  还有什么厉害的放大边权的方法(其实之前已经领教过一次了)ORZ。。。

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. using namespace std;
  8. #define Maxn 5010
  9. #define Maxm 60010
  10. #define INF 0xfffffff
  11. #define LL long long
  12.  
  13. struct node
  14. {
  15. LL x,y,f,o,next;
  16. }t[Maxm*];LL len;
  17. LL first[Maxn];
  18.  
  19. void ins(LL x,LL y,LL f)
  20. {
  21. t[++len].x=x;t[len].y=y;t[len].f=f;
  22. t[len].next=first[x];first[x]=len;t[len].o=len+;
  23. t[++len].x=y;t[len].y=x;t[len].f=;
  24. t[len].next=first[y];first[y]=len;t[len].o=len-;
  25. }
  26.  
  27. LL mymin(LL x,LL y) {return x<y?x:y;}
  28.  
  29. LL w[Maxn],st,ed;
  30. LL dis[Maxn];
  31.  
  32. queue<LL > q;
  33. bool bfs()
  34. {
  35. while(!q.empty()) q.pop();
  36. memset(dis,-,sizeof(dis));
  37. q.push(st);dis[st]=;
  38. while(!q.empty())
  39. {
  40. LL x=q.front();
  41. for(LL i=first[x];i;i=t[i].next) if(t[i].f>)
  42. {
  43. LL y=t[i].y;
  44. if(dis[y]==-)
  45. {
  46. dis[y]=dis[x]+;
  47. q.push(y);
  48. }
  49. }
  50. q.pop();
  51. }
  52. if(dis[ed]==-) return ;
  53. return ;
  54. }
  55.  
  56. LL ffind(LL x,LL flow)
  57. {
  58. if(x==ed) return flow;
  59. LL now=;
  60. for(LL i=first[x];i;i=t[i].next) if(t[i].f>)
  61. {
  62. LL y=t[i].y;
  63. if(dis[y]==dis[x]+)
  64. {
  65. LL a=ffind(y,mymin(flow-now,t[i].f));
  66. t[i].f-=a;
  67. t[t[i].o].f+=a;
  68. now+=a;
  69. }
  70. if(now==flow) break;
  71. }
  72. if(now==) dis[x]=-;
  73. return now;
  74. }
  75.  
  76. LL max_flow()
  77. {
  78. LL ans=;
  79. while(bfs())
  80. {
  81. ans+=ffind(st,INF);
  82. }
  83. return ans;
  84. }
  85.  
  86. bool vis[Maxn];
  87. void dfs(LL x)
  88. {
  89. vis[x]=;
  90. for(LL i=first[x];i;i=t[i].next) if(!vis[t[i].y]&&t[i].f>)
  91. dfs(t[i].y);
  92. }
  93.  
  94. int main()
  95. {
  96. LL n,m;
  97. LL ans=,sum=;
  98. scanf("%lld%lld",&n,&m);
  99. for(LL i=;i<=n;i++) {scanf("%lld",&w[i]);if(w[i]>) ans+=w[i];}
  100. st=n+,ed=st+;
  101. for(LL i=;i<=m;i++)
  102. {
  103. LL x,y;
  104. scanf("%lld%lld",&x,&y);
  105. ins(x,y,INF);
  106. }
  107. for(LL i=;i<=n;i++) if(w[i]>) ins(st,i,w[i]);
  108. for(LL i=;i<=n;i++) if(w[i]<) ins(i,ed,-w[i]);
  109. LL fl=max_flow();
  110. ans-=fl;
  111. memset(vis,,sizeof(vis));
  112. dfs(st);
  113. for(LL i=;i<=n;i++) if(vis[i]) sum++;
  114. printf("%lld %lld\n",sum,ans);
  115. return ;
  116. }

放点不是我写的,比我可信的 最大权闭合子图 解释

1、本题某些东西的解释

本题还有一个要求就是要求不仅要是最大权,并且要求点数还最少
看一个神牛的证明----http://hi.baidu.com/dispossessed/blog/item/2396c0ddbc73a2caa044df44.html

下面证明最小割对应取点方案就是最小取点数
由于原图是个DAG图,所以对于取得的最大权闭合图K,取它的任意一个子图G,如果从K-G仍然是一个闭合图,那么的点权和一定大于等于0,例如:1->2,2->3,1->4,4->5,若最大权闭合图为:{1,2,3,4,5},那么其中任一满足条件的G({1},{1,2},{1,2,3},{1,4},{1,4,5})点权和一定大于等于0,否则去除G,K-G仍然为闭合图,但是K-G的点权和会大于K
所以如果有两种取点方式使得权值相同,但是取点数不同的话,那么肯定存在一个可以移除的满足条件的子图G,其点权和为0
下面考虑构造的网络,对于G在网络中的对应图G',由于在网络求的是最小割,即最大流,而且G的点权和为0,所以G'中与源点S连边的容量和等于G'中与汇点T连边的流量和,同时由于去除G后K还是一个闭合图,所以只有可能G'中的流量流入K'-G',不可能有流量从K'-G'流入G',所以G'的边中除了流量为inf的那些,一定是满流的
再考虑在残留网络中求出取点集的方法,从源点开始floodfill,忽略满流边,即残留网络中的0流边,可以遍历到的点就是要取的点集了,这个道理想一下简单割和闭合图的取法一一对应就可以了
那么G'既然是满流的,在残留网络中就不可能对这些0流边进行处理,那就不会取到G中的点进入取点集,所以建立网络求得得最小割对应的取法取出的就是最小的点数了
--------------------------------

当然还有一种是神奇的放大边权方法

建图前,对所有b[i],执行变换b[i]=b[i]*10000-1,然后,会惊异地发现,
此时最大流所对应的方案就是满足辞退最少人数的了。
为什么?显然,变换后的流量r2除以10000后再取整就等于原来的流量,但是
r2的后四位却蕴含了辞退人数的信息:每多辞退一个人,流量就会少1。

转自:http://blog.csdn.net/sdj222555/article/details/7797534

2、最大权闭合子图

3、ORZ 胡伯涛

太长了不放了,自己看吧。。

2016-11-03 22:00:24

好困Zzz...

【POJ 2987】Firing (最小割-最大权闭合子图)的更多相关文章

  1. 洛谷 - P1361 - 小M的作物 - 最小割 - 最大权闭合子图

    第一次做最小割,不是很理解. https://www.luogu.org/problemnew/show/P1361 要把东西分进两类里,好像可以应用最小割的模板,其中一类A作为源点,另一类B作为汇点 ...

  2. [模拟赛FJOI Easy Round #2][T3 skill] (最小割+最大权闭合子图(文理分科模型))

    [题目描述] 天上红绯在游戏中扮演敏剑,对于高攻击低防御的职业来说,爆发力显得非常重要,为此,她准备学习n个技能,每个技能都有2个学习方向:物理攻击和魔法攻击.对于第i个技能,如果选择物理攻击方向,会 ...

  3. BZOJ.1497.[NOI2006]最大获利(最小割 最大权闭合子图Dinic)

    题目链接 //裸最大权闭合子图... #include<cstdio> #include<cctype> #include<algorithm> #define g ...

  4. Petya and Graph(最小割,最大权闭合子图)

    Petya and Graph http://codeforces.com/contest/1082/problem/G time limit per test 2 seconds memory li ...

  5. HDU 3917 Road constructions(最小割---最大权闭合)

    题目地址:HDU 3917 这题简直神题意... 题目本身就非常难看懂不说..即使看懂了.也对这题意的逻辑感到无语...无论了.. 就依照那题意上说的做吧... 题意:给你n个城市,m个公司.若干条可 ...

  6. [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]

    Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...

  7. 【BZOJ-3438】小M的作物 最小割 + 最大权闭合图

    3438: 小M的作物 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 825  Solved: 368[Submit][Status][Discuss ...

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

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

  9. POJ 2987 Firing | 最大权闭合团

    一个点带权的图,有一些指向关系,删掉一个点他指向的点也不能留下,问子图最大权值 题解: 这是最大权闭合团问题 闭合团:集合内所有点出边指向的点都在集合内 构图方法 1.S到权值为正的点,容量为权值 2 ...

随机推荐

  1. Zepto源码解读

    /*******************************************************************************Zepto核心和dom操作******* ...

  2. window nodejs 版本切换 nvmw

    参考文档:https://cnodejs.org/topic/5338c5db7cbade005b023c98 nvmw 下载到本地 git clone https://github.com/hako ...

  3. 数据搬运工DSS~介绍

    DSS介绍 DSS是为了实现异地数据同步而开发的一套.net平台的应用程序,它寄宿到windows服务上,由多个客户端和一个服务端组成,其中客户端用来收集数据(数据源端),服务端用来将数据写入指定数据 ...

  4. 使用DOM4J解析XMl文件与读取XML文件

    XML文件 <?xml version="1.0" encoding="UTF-8"?> <bookstore> <book id ...

  5. 将文件的编码格式转换为utf-8

    背景:项目中有一些其他部门发过来的代码,编码格式有utf-8,也有GBK,而且是散乱在各个文件夹中的,处理起来十分的麻烦.我想把他们都转成统一的utf-8的格式.代码很简单,直接上代码好了. impo ...

  6. 快速排序算法(C#实现)

    想到了快速排序,于是自己就用C#实现了快速排序的算法: 快速排序的基本思想:分治法,即,分解,求解,组合 . 分解:在 无序区R[low..high]中任选一个记录作为基准(通常选第一个记录,并记为k ...

  7. 关于web项目中中文乱码问题的总结

    关于post和get的中文乱码处理 get: (1)转码:String username=request.getParameter("username");       Strin ...

  8. 配置nginx的负载均衡

    1.1   什么是负载均衡 负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性. 负载均衡,英文名称 ...

  9. (hdu)5652 India and China Origins 二分+dfs

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5652 Problem Description A long time ago there ...

  10. Flash Professional CS6 安装zxp插件

    说明 头两天因工作原因需要使用DragonBones,他的工作方式是的Flash Professional CS5.5以上的环境. DragonBones提供的是一个文件名为:xzp的文件,在Wind ...