POJ 2987 Firing
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 ≤ 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 5
8
-9
-20
12
-10
1 2
2 5
1 4
3 4
4 5
Sample Output
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.
Source
POJ Monthly--2006.08.27, frkstyc
这道题的性质和上一道题差不多,
都是最大闭合权图,
不同的地方在于
1.m的取值与权值无关,这样的话我们让读入的x,y之前的边为INF就好
2.需要求人数,我们重新DFS一遍残余网络,如果这条边还有流量的话,说明需要裁掉这个人,至于为什么,https://wenku.baidu.com/view/986baf00b52acfc789ebc9a9.html
注意几个问题:
1.不要全开long long会超时
2.输出的数不要写反了
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<queue>
6 #define lli long long int
7 using namespace std;
8 const int MAXN=2000001;
9 const int INF = 1e8;
10 inline void read(int &n)
11 {
12 char c='+';int x=0;bool flag=0;
13 while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
14 while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();}
15 n=flag==1?-x:x;
16 }
17 int n,m,s,t;
18 struct node
19 {
20 int u,v,flow,nxt;
21 }edge[MAXN];
22 int head[MAXN];
23 int cur[MAXN];
24 int num=0;
25 int deep[MAXN];
26 lli tot=0;
27 bool vis[MAXN];
28 lli out;
29 void add_edge(int x,int y,int z)
30 {
31 edge[num].u=x;
32 edge[num].v=y;
33 edge[num].flow=z;
34 edge[num].nxt=head[x];
35 head[x]=num++;
36 }
37 void add(int x,int y,int z)
38 {
39 add_edge(x,y,z);
40 add_edge(y,x,0);
41 }
42 bool BFS()
43 {
44 memset(deep,0,sizeof(deep));
45 deep[s]=1;
46 queue<int>q;
47 q.push(s);
48 while(q.size()!=0)
49 {
50 int p=q.front();
51 q.pop();
52 for(int i=head[p];i!=-1;i=edge[i].nxt)
53 if(!deep[edge[i].v]&&edge[i].flow)
54 deep[edge[i].v]=deep[edge[i].u]+1,
55 q.push(edge[i].v);
56 }
57 return deep[t];
58
59 }
60 lli DFS(int now,int nowflow)
61 {
62 if(now==t||nowflow<=0)
63 return nowflow;
64 lli totflow=0;
65 for(int &i=cur[now];i!=-1;i=edge[i].nxt)
66 {
67 if(deep[edge[i].v]==deep[edge[i].u]+1&&edge[i].flow)
68 {
69 int canflow=DFS(edge[i].v,min(nowflow,edge[i].flow));
70 edge[i].flow-=canflow;
71 edge[i^1].flow+=canflow;
72 totflow+=canflow;
73 nowflow-=canflow;
74 if(nowflow<=0)
75 break;
76 }
77
78 }
79 return totflow;
80 }
81 void Dinic()
82 {
83 lli ans=0;
84 while(BFS())
85 {
86 memcpy(cur,head,MAXN);
87 ans+=DFS(s,1e8);
88 }
89 out=tot-ans;
90 }
91 int find_pep(int now)
92 {
93 vis[now]=1;
94 for(int i=head[now];i!=-1;i=edge[i].nxt)
95 if(!vis[edge[i].v]&&edge[i].flow)
96 find_pep(edge[i].v);
97 }
98 int main()
99 {
100 //freopen("a.in","r",stdin);
101 //freopen("c.out","w",stdout);
102 while(~scanf("%d%d",&n,&m))
103 {
104 memset(head,-1,sizeof(head));
105 num=0;
106 s=0,t=n+1;
107 tot=0;
108 for(int i=1;i<=n;i++)
109 {
110 int a;read(a);
111 if(a>0) tot+=a,add(s,i,a);
112 if(a<0) add(i,t,-a);
113 }
114 for(int i=1;i<=m;i++)
115 {
116 int x,y;read(x);read(y);
117 add(x,y,INF);
118 }
119 Dinic();
120 memset(vis,0,sizeof(vis));
121 int ans=0;
122 find_pep(s);
123 for(int i=1;i<=n;i++)
124 ans+=vis[i];
125 //cout<<ans<<" "<<out<<endl;
126 printf("%d %I64dn",ans,out);
127 }
128 return 0;
129 }
- MSBuild入门
- HTTP Basic Authentication验证WCF Data Service
- 移除WordPress 仪表盘首页的“插件”“其它WordPress 新闻”小工具
- 解决VMware 7在Windows 7上无法上网的问题
- Windows Server 2008群集仲裁机制
- [C#2] 5-迭代器
- 服务器未能识别 HTTP 标头 SOAPAction 的值
- 实用代码-C#获取本机网络适配器信息及MAC地址
- WordPress 自定义 login (登录页面)CSS 样式
- [C#1] 12-特性
- HTTP Basic Authentication for RESTFul Service
- [C#2] 4-可空类型、静态类
- jquery 操作css 尺寸
- Windows 7上IIS出现http 500错误
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spark Java UDAF 输入struct嵌套结构
- 深入理解Java内存模型
- Mybatis高级查询(一):resultMap与resultType
- JDK错误用法—TimSort
- Mybatis高级查询(三):分页查询
- 以OpenResty搭建RTB竞价引擎接入层
- 优化Linux bootloader速度的究极之路:从GRUB到EFI Stub
- Linux--nc命令
- Netty之美--I/O模型
- 023.基于IT论坛案例学习Elasticsearch(二):Query高级知识(一)
- 打卡群刷题总结0807——验证二叉搜索树
- 打卡群刷题总结0808——二叉树的层序遍历
- Mybatis高级查询(四):延迟加载
- I/O多路复用器之隐秘的角落
- 打卡群刷题总结0809——二叉树的锯齿形层次遍历