Language:
Default
Firing
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 8744   Accepted: 2631

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 individuallybi (|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

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. #include<iostream>
  2. #include<queue>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<climits>
  6. #define MAXE 65100*2
  7. #define MAXP 5100
  8. #define Max(a,b) a>b?a:b
  9. #define Min(a,b) a<b?a:b
  10. using namespace std;
  11. struct Edge
  12. {
  13. long long int s,t,next;
  14. long long f;
  15. } edge[MAXE];
  16. long long int head[MAXP];
  17. long long int cur[MAXP];
  18. long long int pre[MAXP];
  19. long long int stack[MAXE];
  20. long long int dep[MAXP];
  21. long long int ent;
  22. long long int n,m,s,t,cot;
  23. void add(long long int start,long long int last,long long int f)
  24. {
  25. edge[ent].s=start;
  26. edge[ent].t=last;
  27. edge[ent].f=f;
  28. edge[ent].next=head[start];
  29. head[start]=ent++;
  30. edge[ent].s=last;
  31. edge[ent].t=start;
  32. edge[ent].f=;
  33. edge[ent].next=head[last];
  34. head[last]=ent++;
  35. }
  36. bool bfs(long long int S,long long int T)
  37. {
  38. memset(pre,-,sizeof(pre));
  39. pre[S]=;
  40. queue<long long int>q;
  41. q.push(S);
  42. while(!q.empty())
  43. {
  44. long long int temp=q.front();
  45. q.pop();
  46. for(long long int i=head[temp]; i!=-; i=edge[i].next)
  47. {
  48. long long int temp2=edge[i].t;
  49. if(pre[temp2]==-&&edge[i].f)
  50. {
  51. pre[temp2]=pre[temp]+;
  52. q.push(temp2);
  53. }
  54. }
  55. }
  56. return pre[T]!=-;
  57. }
  58. long long int dinic(long long int start,long long int last)
  59. {
  60. long long int flow=,now;
  61. while(bfs(start,last))
  62. {
  63. long long int top=;
  64. memcpy(cur,head,sizeof(head));
  65. long long int u=start;
  66. while()
  67. {
  68. if(u==last)//如果找到终点结束对中间路径进行处理并计算出该流
  69. {
  70. long long int minn=INT_MAX;
  71. for(long long int i=; i<top; i++)
  72. {
  73. if(minn>edge[stack[i]].f)
  74. {
  75. minn=edge[stack[i]].f;
  76. now=i;
  77. }
  78. }
  79. flow+=minn;
  80. for(long long int i=; i<top; i++)
  81. {
  82. edge[stack[i]].f-=minn;
  83. edge[stack[i]^].f+=minn;
  84. }
  85. top=now;
  86. u=edge[stack[top]].s;
  87. }
  88. for(long long int i=cur[u]; i!=-; cur[u]=i=edge[i].next) //找出从u点出发能到的边
  89. if(edge[i].f&&pre[edge[i].t]==pre[u]+)
  90. break;
  91. if(cur[u]==-)//如果从该点未找到可行边,将该点标记并回溯
  92. {
  93. if(top==)break;
  94. pre[u]=-;
  95. u=edge[stack[--top]].s;
  96. }
  97. else//如果找到了继续运行
  98. {
  99. stack[top++]=cur[u];
  100. u=edge[cur[u]].t;
  101. }
  102. }
  103. }
  104. return flow;
  105. }
  106. void dfs(long long int u)
  107. {
  108. cot++;
  109. dep[u]=;
  110. for(long long int i=head[u];i!=-;i=edge[i].next)
  111. {
  112. long long int v=edge[i].t;
  113. if(!dep[v]&&edge[i].f>)
  114. {
  115. dfs(v);
  116. }
  117. }
  118. }
  119. int main()
  120. {
  121. while(~scanf("%lld%lld",&n,&m))
  122. {
  123. s=;
  124. t=n+;
  125. ent=;
  126. long long int cost,u,v;
  127. long long int ans=;
  128. memset(head,-,sizeof(head));
  129. for(int i=; i<=n; i++)
  130. {
  131. scanf("%lld",&cost);
  132. if(cost>)
  133. {
  134. add(s,i,cost);
  135. ans+=cost;
  136. }
  137. else add(i,t,-cost);
  138. }
  139. for(int i=; i<=m; i++)
  140. {
  141. scanf("%lld%lld",&u,&v);
  142. add(u,v,INT_MAX);
  143. }
  144. memset(dep,,sizeof(dep));
  145. long long int flow=dinic(s,t);
  146. cot=;
  147. dfs(s);
  148. printf("%lld ",cot-);
  149. printf("%lld\n",ans-flow);
  150. }
  151. return ;
  152. }

poj 2987 最大权闭合图的更多相关文章

  1. poj 2987(最大权闭合图+割边最少)

    题目链接:http://poj.org/problem?id=2987 思路:标准的最大权闭合图,构图:从源点s向每个正收益点连边,容量为收益:从每个负收益点向汇点t连边,容量为收益的相反数:对于i是 ...

  2. hdu 2987最大权闭合图模板类型题

    /* 最大权闭合图模板类型的题,考验对知识概念的理解. 题意:如今要辞退一部分员工.辞退每个员工能够的到一部分利益(能够是负的),而且辞退员工,必须辞退他的下属.求最大利益和辞退的最小人数. 最大权闭 ...

  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 网络流 最大权闭合图

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

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

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

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

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

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

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

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

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

  9. POJ 3155 Hard Life 最大密度子图 最大权闭合图 网络流 二分

    http://poj.org/problem?id=3155 最大密度子图和最大权闭合图性质很相近(大概可以这么说吧),一个是取最多的边一个是取最多有正贡献的点,而且都是有选一种必须选另一种的限制,一 ...

随机推荐

  1. linux crontab -r 导致no crontab for root的原因及解决方案

    使用方式 : crontab file [-u user]-用指定的文件替代目前的crontab. crontab-[-u user]-用标准输入替代目前的crontab. crontab-1[use ...

  2. connect VisualVM to Tomcat

    https://blogs.oracle.com/jmxetc/ http://stackoverflow.com/questions/1051817/unable-to-connect-to-tom ...

  3. 简单的鼠标可拖动div 兼容IE/FF

    来源:http://www.cnblogs.com/imwtr/p/4355416.html 作者: 主要思路: 一个div,注册监听onmousedown事件,然后处理获取的对象及其相关值(对象高度 ...

  4. LeetCode "Integer Break"

    A typical CS style DP based solution: class Solution(object): def __init__(self): self.hm = {} def i ...

  5. ElasticSearch安装及部署

    安装及部署 一.环境配置 操作系统:Cent OS 7ElasticSearch版本:1.3.2JDK版本:1.7.0_51SSH Secure Shell版本:XShell 5elasticsear ...

  6. 虚拟机Ubuntu16,caffe环境搭建

    虚拟机下的Ubuntu16.04+caffe+onlycup 官网的step很重要,要跟着官网,的步骤来:http://caffe.berkeleyvision.org/installation.ht ...

  7. Logistic Regression逻辑回归

    参考自: http://blog.sina.com.cn/s/blog_74cf26810100ypzf.html http://blog.sina.com.cn/s/blog_64ecfc2f010 ...

  8. 【javascript基础】5、创建对象

    前言 今天从家里回到了学校,在家呆了十天,胖了几斤的重量,又折腾回学校了,春节回家真是艰辛的路途.随便扯扯我的往返行程:为了省钱我没有选择直飞到长春往返都是到北京转的,这样我和女朋友可以节省4000块 ...

  9. eclipse几个注意的地方

    1.eclipse+tomcat调试java web,eclipse中更新了代码,而tomcat中代码不同步更新 1)双击eclipse tomcat server,勾选"Modules a ...

  10. 3.Sqrt(x)

    要求:Implement int sqrt(int x).  Compute and return the square root of x. 解决方法: 1.牛顿法(Newton's method) ...