/**
题目:poj2987 Firing 最大权闭合子图 边权有正有负
链接:http://poj.org/problem?id=2987
题意:由于金融危机,公司要裁员,如果裁了员工x,那么x的下级都要裁掉,如果x的下级被裁掉,那么x的下级的下级也要裁掉。。。依次类推
每个员工有个价值,公司裁了员工i,获得价值wi(有正有负),
问公司如何裁员获得最大价值。输出裁员人数以及最大价值。
思路:最大权闭合子图。如果员工x价值wx为正,s->x,cap=wx; 如果员工y价值为wx为负,x->t,cap=-wx;
如果员工x是y的上级,x->y,cap=INF;
求s-t最大流,结果为所有正价值之和-最大流。
或者:
求s-t最大流之后,此时dinic的vis为1的点表示在该最小割的S集合内。S集合除去s点的其他点就是需要裁员的人,从中可以获取人数,以及计算价值和。

新增附加源s和附加汇t,从s向所有的正权点引一条边,容量为权值;从所有的负权点向汇点引一条边,容量为负权的相反数。求出最小割以后,S-{s}就是最大闭合子图。 */
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<cstdio>
#include<sstream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = ;
struct Edge{
int from, to, cap, flow;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
struct Dinic{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[N];
bool vis[N];
LL d[N];
int cur[N]; void init(int n)
{
this->n = n;
for(int i = ; i <= n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,));
edges.push_back(Edge(to,from,,));
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS(){
memset(vis, , sizeof vis);
queue<int> Q;
Q.push(s);
d[s] = ;
vis[s] = ;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int i = ; i < G[x].size(); i++){
Edge &e = edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to] = ;
d[e.to] = d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} LL DFS(int x,LL a){
if(x==t||a==) return a;
LL flow = , f;
for(int &i = cur[x]; i < G[x].size(); i++){
Edge& e = edges[G[x][i]];
if(d[x]+==d[e.to]&&(f=DFS(e.to,min(a,(LL)e.cap-e.flow)))>){
e.flow += f;
edges[G[x][i]^].flow -= f;
flow += f;
a -= f;
if(a==) break;
}
}
return flow;
} LL Maxflow(int s,int t){
this->s = s, this->t = t;
LL flow = ;
while(BFS()){
memset(cur, , sizeof cur);
flow += DFS(s,INF);
}
return flow;
}
};
int main()
{
int n, m;
while(scanf("%d%d",&n,&m)==)
{
int s = , t = n+;
Dinic dinic;
dinic.init(t);
int w;
LL sum = ;
for(int i = ; i <= n; i++){
scanf("%d",&w);
if(w>=){
sum += w;
dinic.AddEdge(s,i,w);
}else dinic.AddEdge(i,t,-w);
}
int u, v;
for(int i = ; i <= m; i++){
scanf("%d%d",&u,&v);
dinic.AddEdge(u,v,INF);
}
LL flow = dinic.Maxflow(s,t);
int num = ;
for(int i = ; i <= n; i++){
if(dinic.vis[i]){
num++;
}
}
printf("%d %lld\n",num,sum-flow);
}
return ;
}

poj2987 Firing 最大权闭合子图 边权有正有负的更多相关文章

  1. hdu3879 Base Station 最大权闭合子图 边权有正有负

    /** 题目:hdu3879 Base Station 最大权闭合子图 边权有正有负 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 题意:给出n个 ...

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

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

  3. POJ2987 Firing 最大权闭合图

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

  4. hiho 第119周 最大权闭合子图

    描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编 ...

  5. [HIHO119]网络流五·最大权闭合子图(最大流)

    题目链接:http://hihocoder.com/contest/hiho119/problem/1 题意:中文题意. 由于1≤N≤200,1≤M≤200.最极端情况就是中间所有边都是满的,一共有N ...

  6. 洛谷 P2762 太空飞行计划问题 P3410 拍照【最大权闭合子图】题解+代码

    洛谷 P2762 太空飞行计划问题 P3410 拍照[最大权闭合子图]题解+代码 最大权闭合子图 定义: 如果对于一个点集合,其中任何一个点都不能到达此集合以外的点,这就叫做闭合子图.每个点都有一个权 ...

  7. [HihoCoder1398]网络流五·最大权闭合子图

    题目大意:有$N$项活动$M$个人,每个活动$act_i$有一个正的权值$a_i$,每个人$stu_i$有一个负的权值$b_i$.每项活动能够被完成当且仅当该项活动所需的所有人到场.如何选择活动使最终 ...

  8. 洛谷 P2762 太空飞行计划问题 【最大权闭合子图+最小割】

    --一道难在读入的题. 最后解决方案直接getline一行然后是把读优拆掉放进函数,虽然很丑但是过了. 然后就是裸的最大权闭合子图了,把仪器当成负权点向t连流量为其价格的边,s向实验连流量为实验报酬的 ...

  9. 【POJ 2987】Firing (最小割-最大权闭合子图)

    裁员 [问题描述] 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误.给出每个人的贡献值和 ...

随机推荐

  1. socket网络编程基础小记

    "一切皆Socket!" 话虽些许夸张.可是事实也是,如今的网络编程差点儿都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间怎样通 ...

  2. Maven仓库设置代理

    线上服务器是没有外网环境的, 添加代理配置如下: <settings>     ...    <proxies>       <proxy>          &l ...

  3. 【Linux】Ubuntu vi 上下左右变ABCD及 apt-get install报错问题解决方法

    新装的ubuntu12.04,本人绝对新手,在使用VI编辑器编辑文本时觉得实在是难用,因此找了几个解决方法如下: 1. 安装vim full版本 由于Ubuntu预安装的是tiny版本,就会导致我们在 ...

  4. (转)Scala中协变(+)、逆变(-)、上界(<:)、下界(>:)简单介绍

    看源码的时候看到: trait ExtensionId[T <: Extension] { 没见过这个符号啊<: Scala上界(<:)和下界(>:) 1) U >: T ...

  5. [Angular] Improve Server Communication in Ngrx Effects with NX Data Persistence in Angular

    Communicating with a remote server via HTTP presents an extra level of complexity as there is an inc ...

  6. Jconsole

    Jconsole 1.1 简介以及连接 JConsole是一个基于JMX的GUI工具,用于连接正在运行的JVM,它是Java自带的简单性能监控工具.下面以对tomcat的监控为例,带领大家熟悉Jcon ...

  7. ARM 指令集版本和ARM 版本z

    a9是cortex-a9的简称,属于v7指令集,属于目前比较新的了.arm9就是arm9,属于v5指令集,arm9后面的是arm11,属于v6指令集,之前的是arm7,属于v4指令集.虽然他们之间差别 ...

  8. 数学之路-分布式计算-linux/unix技术基础(4)

    pwd显示当前文件夹,ls查看文件夹下的文件,cd 进入文件夹 -bash-4.2$ pwd /home/myhaspl-bash-4.2$ lsabc        hadoop-2.4.1     ...

  9. MyEclipse 注释乱码问题

    解决MyEclipse 中 import项目,注释是乱码问题:

  10. DevExpress SpinEdit控件使用实例——删除ASPxSpinEdit右边的上下小箭头SpinButtons-ShowIncrementButtons

    使用ASPxSpinEdit来添加数字类型的输入框: 默认情况下, SpinEdit通过点击右边的上下箭头来加减number,下面的代码是去掉上下箭头,内容居中显示,并将边框颜色置为白色: <d ...