/**
题目: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. Spark详解

    原文连接 http://xiguada.org/spark/ Spark概述 当前,MapReduce编程模型已经成为主流的分布式编程模型,它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的 ...

  2. BS中保存参数

    开发中经常需要将值存起来,当点击某一项时以便知道点击了哪一项. 一:应用JS页面跳转(牛腩中讲到) HTML: <td class="txt c"><a href ...

  3. 解决tomcat提交的数据乱码的问题

    有时,开发过程中会遇到前端传入“中文”并返回时,会出现乱码!主要是因为前端通过tomcat7提交的数据就出现了乱码的问题,也就说根源在于tomcat7. 有2中方案解决该问题: (1)使用tomcat ...

  4. Google 收购 Android 十周年 全面解读Android现状

    --訪传智播客Android学科教学总监传智·平一指 Android以前是一家创立于旧金山的公司的名字,该公司于2005年8月份被Google收购,并从此踏上了飞速发展的道路.经过十年的发展,它已经发 ...

  5. 【Python】学习笔记八:面向对象

    举例 面向对象的合理解释就是:我是人这个类,对象化以后我就是一个个体OLIVER 对象化就是在人这个大类中,将某个人指名道姓,具体到某个人 下面是一个具体的实例一: #!/usr/bin/python ...

  6. Unix 网络编程 dup和dup2函数

    dup和dup2也是两个很实用的调用,它们的作用都是用来复制一个文件的描写叙述符. 它们经经常使用来重定向进程的stdin.stdout和stderr.这两个函数的原形例如以下: #include & ...

  7. DDL语句--改动表

    改动表是指改动数据库中已经存在的表的定义.改动表比又一次定义表简单.不须要又一次载入数据.也不会影响正在进行的服务. MySQL中通过ALTER TABLE语句来改动表.改动表包含改动表名.改动字段数 ...

  8. 哪种代理适合用于Web数据采集

    在Web数据采集中为了避免被服务器封锁而通过代理下载的情况很常见.但是,并非所有的代理都适合于Web数据采集.下面是鲲鹏数据的技术人员给出的说明. 根据HTTP代理的匿名性可以将其分为以下几种:   ...

  9. Python 使用 UTF-8 编码(转)

    Python 使用 UTF-8 编码(转) 原文出处:http://blog.chenlb.com/2010/01/python-use-utf-8.html 一般我喜欢用 utf-8 编码,在 py ...

  10. 转:C#操作摄像头

    转自: http://blog.csdn.NET/chenhongwu666/article/details/40594365 如有雷同,不胜荣幸,若转载,请注明 最近做项目需要操作摄像头,在网上百度 ...