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 ≤ ij ≤ n) meaning the i-th employee has the j-th employee as his direct underling.

题意:

裁员吧,给出每个员工的价值(有的人是负的),给出员工的直属关系,裁掉领导就必须裁下属,可能成环,问怎样裁员才能得到最大利益,如果有多解,输出裁员人数最少的那一个。

解题思路:

求最大闭合权图,(闭合图就是该图中每个点都不能连到此图外面去)。

方法:把价值为证的员工连接源点,价值为负的员工连接汇点,然后根据直属关系连接两种员工,在该图上跑一遍最大流(我用的Dinic),然后以求出的最小割为界,连接原点的那一部分就是保留下来的员工。

最小割大概就是:水流从原点出发,把最先遇到的一系列满流路径,用一条线贯穿,割线左边的集合跟源点联通,右边的集合跟汇点联通。吧?

代码:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=5000+10;
const int MAXM=60000*2+5000*2;
int n,m;
int s,t,e_max,fir[MAXN],dis[MAXN];
int val[MAXN];
int vis[MAXN];
int number;
long long profit;
int q[999999];
struct
{int u,v,rflow,nex;   //rflow是残余流量
}edge[MAXM];
void add_edge(int u,int v,int rflow)
{edge[e_max].u=u;edge[e_max].v=v;edge[e_max].rflow=rflow;edge[e_max].nex=fir[u];fir[u]=e_max++;edge[e_max].u=v;edge[e_max].v=u;edge[e_max].rflow=0;edge[e_max].nex=fir[v];fir[v]=e_max++;
}
void init()
{memset(fir,-1,sizeof(fir));e_max=0;
}
int bfs()
{int i,x,v,r=1,f=0;memset(dis,0,sizeof(dis));dis[s]=1;q[0]=s;while(f<r){x=q[f++];for(i=fir[x];i!=-1;i=edge[i].nex)if(edge[i].rflow&&dis[v=edge[i].v]==0){dis[v]=dis[x]+1;if(v==t)return 1;q[r++]=v;}}return 0;
}
int dfs(int s,int limit)
{if(s==t)return limit;int i,v,tmp,cost=0;for(i=fir[s];i!=-1;i=edge[i].nex)if(edge[i].rflow&&dis[s]==dis[v=edge[i].v]-1){tmp=dfs(v,min(limit-cost,edge[i].rflow));if(tmp>0){edge[i].rflow-=tmp;             //修改残余网络edge[i^1].rflow+=tmp;cost+=tmp;if(limit==cost)break;}else dis[v]=-1;                   //标记为-1以后不再访问}return cost;
}
int Dinic()
{s=0,t=n+1;int ans=0;while(bfs())                              //bfs(分层)ans+=dfs(s,INF);                      //dfs()按层级寻找增广路,起点流量无限制return ans;
}
void RAM()
{init();for(int i=1;i<=n;i++){cin>>val[i];if(val[i]>=0)add_edge(0,i,val[i]);elseadd_edge(i,n+1,(-1)*val[i]);}for(int i=1;i<=m;i++){int a,b;cin>>a>>b;add_edge(a,b,INF);}
}
void bfs2()
{memset(vis,0,sizeof vis);number=0;profit=0;int f=0,r=1;q[0]=s;vis[0]=1;while(f<r){int now=q[f++];for(int i=fir[now];~i;i=edge[i].nex){if(edge[i].rflow!=0&&!vis[edge[i].v]){vis[edge[i].v]=1;number++;profit+=val[edge[i].v];q[r++]=edge[i].v;}}}
}
int main()
{while(cin>>n>>m){RAM();Dinic();bfs2();cout<<number<<' '<<profit<<endl;}
}

POJ 2987 Firing 最大权闭合图相关推荐

  1. poj 2987 Firing (最大权 闭合 图)

    http://poj.org/problem?id=2987 题意: 公司要由于经济 问题 要 裁员工,已知,要采取某个 员工,那么 他的下属也将被 裁去,给出  裁出 n  个员公的 所获的利益 ( ...

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

    题目链接:点击查看 题目大意:某公司想要裁员,裁员的标准是如果某人被裁,那么其下属也会被裁,依此类推,每一个人都有一个贡献度,问怎样裁员才能使得最后的贡献度最大并且裁掉人数最少 题目分析:最大权闭合图 ...

  3. POJ2987 Firing 最大权闭合图

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

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

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

  5. 【POJ - 2987】Firing(最大权闭合图,网络流最小割,输出方案最小,放大权值法tricks)

    题干: You've finally got mad at "the world's most stupid" employees of yours and decided to ...

  6. 【POJ - 2987 】Firing 【最大权闭合图有唯一的 势 】

    You've finally got mad at "the world's most stupid" employees of yours and decided to do s ...

  7. POJ2987-Firing(最大权闭合图)

    Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 10904   Accepted: 3290 Descript ...

  8. luogu P3410 拍照(最大权闭合图转最小割)

    luogu P3410 拍照 最大权闭合图转最小割 要得到最大收益,我们可以用总可能收益减去最小花费,也就是最小割. #include<cstdio> #include<cstrin ...

  9. 【网络流24题】B、太空飞行计划问题(最大权闭合图转最小割、最小割方案输出)

    整理的算法模板合集: ACM模板 B.太空飞行计划问题(最大权闭合图转最小割.最小割方案输出)[省选/NOI- ] P2762 太空飞行计划问题 [问题分析] 最大权闭合图问题,可以转化成最小割问题, ...

最新文章

  1. 时间一天一天过去,很快;时间如果过的慢,更是没有意思
  2. boost::notify_all_at_thread_exit相关的测试程序
  3. 他来了他来了!阿里云混合云全新升级高燃来袭!
  4. android开源库收集
  5. Raspberry Pi(树莓派)试用小记
  6. Leetcode 410.分割数组的最大值(最优解是二分法)
  7. codevs1519 过路费(最小生成树+LCA)
  8. 网站类项目商业计划书(转)
  9. 计算机中word音乐符号在哪里找,word音乐符号怎么输入?小编告诉你
  10. eclipse中的英文与汉语对照表
  11. Using platform encoding (UTF-8 actually) to copy filtered resources错误
  12. jdbc连接mysql数据库,设置字符集编码
  13. 【lc3】汇编实现I/O中断
  14. 人工智能:确定性推理
  15. 读书笔记:《好团队激活个人--猫鼬教你如何带团队》
  16. Android OpenCV 身份证识别实战
  17. Java实现三位数的水仙花数计算
  18. Python123 期末题库
  19. c语言rsi2010中制运行,汇编语言初探(控制类指令)-来自第三章3.6的笔记-P135-P163
  20. 图灵杯 蔡老板的会议

热门文章

  1. 《微波技术基础》第二版 阅读随笔2
  2. Java笔记:常用类
  3. Android WebView加载网页,图片等元素宽度大小不兼容手机屏幕的宽度
  4. 超融合进入云轨道 青云QingCloud一鸣惊人
  5. leetcode 百题大战
  6. 2014电大计算机基础考核册答案,电大计算机本科【计算机数学基础(1)】形成性考核册答案(附完整题目)...
  7. 算法笔记之旅 | 日期之间天数计算
  8. 姑苏拟秋裤邻近建楼房 摩天大楼泡沫隐现
  9. 超融合微软服务器许可授权,微软Windows Server 2016转向按核心授权许可
  10. SSD固态硬盘消失不认盘丢盘,死机卡顿30分钟大法恢复修复!!