题意:给出一个有向图,选择一个点,则要选择它的可以到达的所有节点。选择每个点有各自的利益或损失。求最大化的利益,以及此时选择人数的最小值。

算法:构造源点s汇点t,从s到每个正数点建边,容量为利益。每个负点到t建边,容量为损失的绝对值。其他关系边容量正向无穷,反向0。正数点总和减去最小割即为最大权闭合图答案。因为残余网络不会对0流边处理,所以不会将0流点选入取点集,所以最小割的取法中为被选中的点。

最大权闭合图的求解方法:

  1. 先构造网络流N,添加源点s,从s到正权值点做一条边,容量为点的权值。

  2. 添加汇点t,从负权值点到t做一条边,容量为点的权值的绝对值。

  3. 原来的边的容量统统设为无穷大。比如:

    转换为

  4. 求解最小割:最大权=正权值之和-最小割权值

  5. 残余网络中的点的个数即为裁员个数。

思路:最大权闭合图。用Dinic求最小割

要得到最大收益,就是尽量选择更多收益为正数的人,选择更少收益为负数的人,因此我们将收益为正数的人与源点连一条边,将收益为负数的人与汇点连一条边,这样得到的割集就是未选择的收益为正数的人+选择的收益为负数的人(也可以是损失的收益),要使这个割集越小越好,那么就是求最小割。最大收益是所有正数的和sum,再用sum-最小割(损失的收益)就可以得到最大收益。

最少的裁员人数,最小割后的的残余网络中,只要能从S遍历到的点,就可以看成是被裁掉的点,因为最终肯定会遇到割边达不到T,所以我们直接DFS残余网络的点数就可以得到最少的裁员人数了。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
typedef long long LL; const LL INF = 0x3f3f3f3f3f3f3f3f; struct edge
{
edge(int _v,int _r, LL _c):v(_v),r(_r),c(_c){};
int v,r;
LL c;
}; vector<edge> e[]; void add_edge(int u,int v,LL c)
{
e[u].push_back(edge(v,e[v].size(),c));
e[v].push_back(edge(u,e[u].size()-,));
} int level[];
int iter[]; // 当前弧,在其之前的边已经没有用了
queue<int> q; bool bfs(int s,int t)
{
memset(level,, sizeof(level));
while (!q.empty()) q.pop();
q.push(s);
level[s]=;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=;i<e[u].size();i++)
{
int v=e[u][i].v;
if(e[u][i].c>&&!level[v])
{
q.push(v);
level[v]=level[u]+;
}
if(level[t])return ;
}
}
return ;
} LL dfs(int s,int t, LL flow)
{
if(s==t)return flow;
for(int& i = iter[s];i<e[s].size();i++) // 一次增广返回时,记录当前弧
{
int v = e[s][i].v;
if(e[s][i].c>&&level[v]==level[s]+)
{
LL k = dfs(v,t,min(flow,e[s][i].c));
if(k>)
{
e[s][i].c-=k;
e[v][e[s][i].r].c+=k;
return k;
}
}
}
return ;
} LL Dinic(int s,int t)
{
LL flow=;
while(bfs(s,t))
{
LL f=;
memset(iter, , sizeof(iter));
while((f=dfs(s,t,INF))>)flow+=f;
}
return flow;
} bool vis[];
int cnt;
void GaoCnt(int u)//dfs统计残余图的正边
{
++cnt;
vis[u]=;
for(int i=;i<e[u].size();i++)
{
int v=e[u][i].v;
if(e[u][i].c>&&!vis[v])
GaoCnt(v);
}
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
int s=,t=n+;// 源点,汇点
LL ans=;
for(int i=;i<=n;i++)
{
LL c;
scanf("%lld",&c);
if(c>)
{
ans+=c; //正权值求和
add_edge(s,i,c);
}
else if(c<)
{
add_edge(i,t,-c);
}
}
for (int i = ; i < m; ++i) {
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v,INF);
}
ans-= Dinic(s,t);
GaoCnt(s);
printf("%d %lld\n",cnt-,ans);
return ;
}

参考自:hankcsyogykwan

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. [luoguP2762] 太空飞行计划问题(最大权闭合图—最小割—最大流)

    传送门 如果将每一个实验和其所对的仪器连一条有向边,那么原图就是一个dag图(有向无环) 每一个点都有一个点权,实验为收益(正数),仪器为花费(负数). 那么接下来可以引出闭合图的概念了. 闭合图是原 ...

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

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

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

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

  5. B1391 [Ceoi2008]order 最大权闭合图 最小割

    啊啊啊,假的题吧!!!我用的当前弧优化T了6个点,其他人不用优化AC!!!震惊!!!当前弧优化是假的吧!!! 到现在我也没调出来...大家帮我看看为啥70.... 来讲一下这个题的思路,就是设一个源点 ...

  6. POJ2987 Firing 最大权闭合图

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

  7. 洛谷 P4174 [NOI2006]最大获利 && 洛谷 P2762 太空飞行计划问题 (最大权闭合子图 && 最小割输出任意一组方案)

    https://www.luogu.org/problemnew/show/P4174 最大权闭合子图的模板 每个通讯站建一个点,点权为-Pi:每个用户建一个点,点权为Ci,分别向Ai和Bi对应的点连 ...

  8. BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)

    题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...

  9. 【最大权闭合子图 最小割】bzoj1497: [NOI2006]最大获利

    最大权闭合子图的模型:今天才发现dinic板子是一直挂的…… Description 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU集团旗下的CS&T通讯公司在 ...

随机推荐

  1. C/S 开发框架 ----- 广州本地

    C/S 开发框架 -----  广州本地: 1) 爱奇迪    http://www.iqidi.com       发现一个源码出售站   http://www.51aspx.com/code/co ...

  2. Python os.walk文件遍历用法【转】

    python中os.walk是一个简单易用的文件.目录遍历器,可以帮助我们高效的处理文件.目录方面的事情. 1.载入 要使用os.walk,首先要载入该函数 可以使用以下两种方法 import os ...

  3. libunistring-0.9.9

    Introduction to libunistring Text files are nowadays usually encoded in Unicode, and may consist of ...

  4. 031_keepalive+nginx保证nginx高可用

    一. yum -y install keepalived keepalived配置: keepalived.conf: vrrp_instance proxy { state BACKUP inter ...

  5. SpringMVC拦截器(慕课网)

    拦截器:通过统一拦截从浏览器发往服务器的请求来完成功能的增强 使用场景:解决请求的共性问题 如:乱码.权限验证 基本工作原理:拦截器和过滤器的工作原理相似 乱码问题:使用Spring过滤器(Filte ...

  6. ansible笔记(9):常用模块之包管理模块

    ansible笔记():常用模块之包管理模块 yum_repository模块 yum_repository模块可以帮助我们管理远程主机上的yum仓库. 此处我们介绍一些yum_repository模 ...

  7. redis递减,过期返回值

    2017年4月24日 18:23:07 星期一 $key = 'abc'; $redis = IRedis::getInstance(); $a = $redis->setex($key, 1, ...

  8. UDP/TCP拾遗

    1.UDP的特点 (1)UDP 是无连接的,即发送数据之前不需要建立连接. (2)UDP 使用尽最大努力交付,即不保证可靠交付,同时也不使用拥塞控制. (3)UDP 是面向报文的.UDP 没有拥塞控制 ...

  9. YUV的数据格式

    一.YUV格式分为两大类:planar(平面)和packed(打包).planar格式,先连续存储所有像素点的Y分量,紧接着存储所有像素点的U,随后存储所有像素点的V.packed格式,每个像素点的Y ...

  10. 关于在Fragment中设置toolbar及菜单的方法

    在NoActionBar的主题中onCreateOptionsMenu方法不会运行,这里就需要将toolbar强制转换为ActionBar 在加入toolbar的监听之类后需要在onCreateVie ...