POJ 2987 Firing (最大权闭合图,最小割)
来源:互联网 发布:贵州省茶叶出口数据 编辑:程序博客网 时间:2024/05/18 01:48
http://poj.org/problem?id=2987
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 ≤ i, j ≤ 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
5 58-9-2012-101 22 51 43 44 5
Sample Output
2 2
Hint
Source
网络流。。。好强大。。。orz。。。
题意:
你的公司要裁员,裁掉某个员工可能会获得收益或损失金钱,如果裁掉某个员工,他所有的下属(直接/间接)也要被裁掉,一个员工可能有多个上级和下属,求最大收益及其最少人数。
分析:
点为员工,上级到下级之间连一条有向边,我们最后要求一个图,这个图是封闭的,即没有出边,使得点的权值和(获得/损失)最大,即求最大权闭合图。
最大权闭合图可转化为网络流解,此处仅给出方法,具体证明请参见Amber大神的《最小割模型在信息学竞赛中的应用》。
方法:
1.原图中的有向边的容量设为无穷大;
2.增加源点,连向点权为正的点,容量为点权;
3.增加汇点,点权为负的点连向汇点,容量为点权的绝对值;
4.求解该图的最小割,最大权和为正点权和减最小割;
5.在残留网络中进行深度优先搜索,去掉源点,即为最大权闭合图。
#include<cstdio>#include<iostream>#include<cstdlib>#include<algorithm>#include<ctime>#include<cctype>#include<cmath>#include<string>#include<cstring>#include<stack>#include<queue>#include<list>#include<vector>#include<map>#include<set>#define sqr(x) ((x)*(x))#define LL long long#define itn int#define INF 0x3f3f3f3f#define PI 3.1415926535897932384626#define eps 1e-10#define maxm 70007<<1#define maxn 5007using namespace std;const long long INFLL=0x3f3f3f3f3f3f3f3f;int fir[maxn];int u[maxm],v[maxm],nex[maxm];long long cap[maxm],flow[maxm];int e_max;int iter[maxn],q[maxn],lv[maxn];void add_edge(int _u,int _v,long long _w){ int e; e=e_max++; u[e]=_u;v[e]=_v;cap[e]=_w; nex[e]=fir[u[e]];fir[u[e]]=e; e=e_max++; u[e]=_v;v[e]=_u;cap[e]=0; nex[e]=fir[u[e]];fir[u[e]]=e;}void dinic_bfs(int s){ int f,r; memset(lv,-1,sizeof lv); q[f=r=0]=s; lv[s]=0; while(f<=r) { int x=q[f++]; for (int e=fir[x];~e;e=nex[e]) { if (cap[e]>flow[e] && lv[v[e]]<0) { lv[v[e]]=lv[u[e]]+1; q[++r]=v[e]; } } }}long long dinic_dfs(int _u,int t,long long _f){ if (_u==t) return _f; for (int &e=iter[_u];~e;e=nex[e]) { if (cap[e]>flow[e] && lv[_u]<lv[v[e]]) { long long _d=dinic_dfs(v[e],t,min(_f,cap[e]-flow[e])); if (_d>0) { flow[e]+=_d; flow[e^1]-=_d; return _d; } } } return 0;}long long max_flow(int s,int t){ memset(flow,0,sizeof flow); long long total_flow=0; for (;;) { dinic_bfs(s); if (lv[t]<0) return total_flow; memcpy(iter,fir,sizeof iter); long long _f; while ((_f=dinic_dfs(s,t,INF))>0) total_flow+=_f; } return total_flow;}int cnt=0;bool vis[maxn];void dfs(int _u){ cnt++; vis[_u]=true; for (int e=fir[_u];~e;e=nex[e]) if (!vis[v[e]] && cap[e]>flow[e]) dfs(v[e]);}int main(){ #ifndef ONLINE_JUDGE freopen("/home/fcbruce/文档/code/t","r",stdin); #endif // ONLINE_JUDGE int n,m,w; long long W=0; scanf("%d%d",&n,&m); int s=0,t=n+1; e_max=0; memset(fir,-1,sizeof fir); for (int i=1;i<=n;i++) { scanf("%d",&w); if (w>0) { W+=w; add_edge(s,i,w); } if (w<0) { add_edge(i,t,-w); } } int _u,_v; for (int i=0;i<m;i++) { scanf("%d%d",&_u,&_v); add_edge(_u,_v,INFLL); } long long max_profit=W-max_flow(s,t); memset(vis,0,sizeof vis); dfs(s); printf("%d %I64d\n",--cnt,max_profit); return 0;}
- POJ 2987 Firing (最大权闭合图,最小割)
- POJ 2987 Firing 最小割(最大权闭合子图)
- POJ2987 Firing 最大权闭合图,最小割
- poj 2987 Firing ------最大权闭合图
- poj 2987 Firing(最大权闭合图)
- POJ 2987 Firing (最大权闭合图)
- POJ 2987 Firing 最大权闭合图
- poj 2987 Firing 最大权闭合图
- POJ 2987 Firing 最大权闭合图
- POJ 2987 Firing 最大权闭合图
- poj 2987 Firing 最大权闭合图
- POJ 2987 Firing 【最大权闭合图】
- POJ 2987 最大流最小割最大权闭合图
- POJ 2987 (最大权闭合图 最小割)
- POJ 2987 Firing(最大权闭合)
- POJ 2987 Firing(最大权闭合)
- poj Firing(最大权闭合图)
- POJ 2987 Firing (最大权闭合子图Dinic)
- [2014-08-08]JAVA笔记_Collection(集合)
- HDU 4923 Room and Moor【栈】【想法】
- 方法的重载
- 64/32位win7/8中VS2012+CUDA6.0配置
- HDOJ1020
- POJ 2987 Firing (最大权闭合图,最小割)
- Oracle笔记之用户管理2
- 微软下一代网站开发框架:ASP.NET MVC 6 新特性揭秘
- (1,(2,3),(4,(5,6),7))变成:(1,2,3,4,5,6,7)
- Android 4.04编译错误及更改方法整理
- ASP.NET获取客户端IP地址相关方法
- MySQL表损坏预防与修复
- 反转一个栈
- 转:int型变量占多少个字节?