【题目链接】 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. 抓包工具 - Fiddler - (二)

    <转载自 miantest> 在上一篇中介绍了Fiddler的基本使用方法.通过上一篇的操作我们可以直接抓取浏览器的数据包.但在APP测试中,我们需要抓取手机APP上的数据包,应该怎么操作 ...

  2. mac虚拟机上(centos系统)设置联网第二种方式

    这种方式简单,不容易出错,用的桥接的方式. 这样的安装的centos会得到ip地址 然后编辑一下网卡配置,使其变为静态得ip 输入命令 # vi /etc/sysconfig/network-scri ...

  3. Android记事本05

    昨天: intentFilter 今天: URL和logcat 问题: ADK更新后无法打开布局文件.xml

  4. 【bzoj4822/bzoj1935】[Cqoi2017]老C的任务/[Shoi2007]Tree 园丁的烦恼 树状数组

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825530.html bzoj4822 题目描述 老 C 是个程序员.     最近老 C 从老板那里接到了一个任务 ...

  5. Bsd内核选项总结

    Bsd内核选项总结 一: 下面这个选项在每个内核中都要有: machine i386 它指明了机器的硬件体系结构.它必须是i386, pc98, sparc64, alpha, ia64, amd64 ...

  6. [bzoj3601] 一个人的数论 [莫比乌斯反演+高斯消元]

    题面 传送门 思路 这题妙啊 先把式子摆出来 $f_n(d)=\sum_{i=1}^n[gcd(i,n)==1]i^d$ 这个$gcd$看着碍眼,我们把它反演掉 $f_n(d)=\sum_{i=1}^ ...

  7. BZOJ1233 [Usaco2009Open]干草堆tower 【单调队列优化dp】

    题目链接 BZOJ1233 题解 有一个贪心策略:同样的干草集合,底长小的一定不比底长大的矮 设\(f[i]\)表示\(i...N\)形成的干草堆的最小底长,同时用\(g[i]\)记录此时的高度 那么 ...

  8. 中英文混截,一个中文相当于n个英文

    项目中遇到这么个需求,截取中英文字符串,一个中文相当于2个英文,全英文时截取12个英文字母,全中文时是6个中文汉字,中英文混合时是12个字节,在网上有找到这样的解决方案,但我没能静下心来研究懂,于是自 ...

  9. 日常收集整理些js经典实例

    跨浏览器添加事件 //跨浏览器添加事件 function addEvent(obj,type,fn){ if(obj.addEventListener){ obj.addEventListener(t ...

  10. a标签打电话

    <a href="tel:0147-88469258"></a> <a href="mailto:bd@pangxiekeji.com&qu ...