【题目链接】 http://poj.org/problem?id=2987

【题目大意】

  为了使得公司效率最高,因此需要进行裁员,
  裁去不同的人员有不同的效率提升效果,当然也有可能是负的效果,
  如果裁去一个上级,那么他所管辖的下级需要全部裁掉,问最大效率提升
  同时求出最小裁员

【题解】

  我们从上司向所有的下属连线会发现裁去的部分恰是一个最大权闭合图
  所以按照最大权闭合图建图求最小割,残余网络就是裁员数量。

【代码】

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX_V=5010;
typedef long long LL;
struct edge{int to;LL cap;int rev;};
vector<edge> G[MAX_V];
int V,level[MAX_V],iter[MAX_V];
void add_edge(int from,int to,int cap){
G[from].push_back((edge){to,cap,G[to].size()});
G[to].push_back((edge){from,0,G[from].size()-1});
}
void bfs(int s){
memset(level,-1,sizeof(level));
queue<int> que;
level[s]=0;
que.push(s);
while(!que.empty()){
int v=que.front(); que.pop();
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&level[e.to]<0){
level[e.to]=level[v]+1;
que.push(e.to);
}
}
}
}
LL dfs(int v,int t,LL f){
if(v==t)return f;
for(int &i=iter[v];i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&level[v]<level[e.to]){
LL d=dfs(e.to,t,min(f,e.cap));
if(d>0){
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}return 0;
}
LL max_flow(int s,int t){
LL flow=0;
for(;;){
bfs(s);
if(level[t]<0)return flow;
memset(iter,0,sizeof(iter));
LL f;
while((f=dfs(s,t,INF))>0){
flow+=f;
}
}
}
const int MAX_N=5000;
const int MAX_M=60000;
int N,M,w[MAX_N],a[MAX_M],b[MAX_M];
LL max_weight_closure(int s,int t){
LL W=0; V=t;
for(int i=0;i<=V;i++)G[i].clear();
for(int i=0;i<N;i++){
if(w[i]>0)W+=w[i],add_edge(s,i,w[i]);
if(w[i]<0)add_edge(i,t,-w[i]);
}
for(int i=0;i<M;i++){
add_edge(a[i]-1,b[i]-1,INF);
}
return W-max_flow(s,t);
}
int leftv,vis[MAX_V];
void cal_res_net(int v){
++leftv;
vis[v]=1;
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&!vis[e.to])cal_res_net(e.to);
}
}
void init(){
for(int i=0;i<N;i++)scanf("%d",&w[i]);
for(int i=0;i<M;i++)scanf("%d%d",&a[i],&b[i]);
}
void solve(){
int s=N,t=N+1;
LL max_profit=max_weight_closure(s,t);
memset(vis,0,sizeof(vis));
leftv=0;
cal_res_net(s);
printf("%d %lld\n",--leftv,max_profit);
}
int main(){
while(~scanf("%d%d",&N,&M)){
init();
solve();
}return 0;
}

POJ 2987 Firing(最大权闭合图)的更多相关文章

  1. poj 2987 Firing 最大权闭合图

    题目链接:http://poj.org/problem?id=2987 You’ve finally got mad at “the world’s most stupid” employees of ...

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

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

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

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

  4. POJ2987 Firing 最大权闭合图

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

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

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

  6. POJ 2987 Firing 网络流 最大权闭合图

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

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

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

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

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

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

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

随机推荐

  1. 爬虫:Scrapy15 - 调试(Debugging)Spiders

    考虑下面的 spider: import scrapy from myproject.items import MyItem class MySpider(scrapy.Spider): name = ...

  2. 《大道至简》第一章 编程的精义 java伪代码形式

    愚公.这位名家身上,浓缩了项目组织者.团队经理.编程人员.技术分析师等众多角色的优秀素质. 愚公移山事件分析: 原始需求:惩山北之塞,出入之迂 项目沟通方式:聚室而某曰 项目目标:毕力平险,指通豫南, ...

  3. string 与 byte[] 互转时的注意事项

    1.string 转 byte[] //为UTF8编码 byte[] midbytes=isoString.getBytes("UTF8"); //为ISO-8859-1编码,其中 ...

  4. 【bzoj4010】[HNOI2015]菜肴制作 拓扑排序+堆

    题目描述 给你一张有向图,问:编号-位置序(即每个编号的位置对应的序列)最小(例如1优先出现在前面,1位置相同的2优先出现在前面,以此类推)的拓扑序是什么? 输入 第一行是一个正整数D,表示数据组数. ...

  5. POJ3585 Accumulation Degree 【树形dp】

    题目链接 POJ3585 题解 -二次扫描与换根法- 对于这样一个无根树的树形dp 我们先任选一根进行一次树形dp 然后再扫一遍通过计算得出每个点为根时的答案 #include<iostream ...

  6. position:absolute和float隐式改变display为inline-block

    不论之前是什么类型的元素(display:none除外), 只要设置了position:absolute或float, 都会让元素以display:inline-block的方式显示, 可以设置长宽, ...

  7. 国旗计划(flag)

    国旗计划(flag) 题目描述 A国正在开展一项伟大的计划--国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这项计划需要多名边防战士以接力的形式共同完成,为此,国土安全局已经挑选了n名 ...

  8. 【CZY选讲·Yjq的棺材】

    题目描述 Yjq想要将一个长为宽为的矩形棺材(棺材表面绝对光滑,所以棺材可以任意的滑动)拖过一个L型墓道. 如图所示,L型墓道两个走廊的宽度分别是和,呈90°,并且走廊的长度远大于. 现在Hja ...

  9. [解决方案]Senparc.CO2NET 初始编译报错的问题

    Senparc.CO2NET.Sample.net45 如果点击重新生成,报一下错误,那么解决办法如下: 解决方案: 1.Windows + R 打开运行,输入Regedit 2.找到项目录HKEY_ ...

  10. Windows Server 创建环回网卡

    1.以管理员身份运行cmd后,在cmd命令窗口中执行:hdwwiz 启动硬件添加向导. 2.在添加硬件向导中选择手动安装或自动搜索都可以.然后选择网络适配器. 3.选择网络适配器:厂商选择Micros ...