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

Time Limit: 5000MS Memory Limit: 131072K

Description

You’ve finally got mad at “the world’s most stupid” employees of yours and decided to do some firings. You’re now simply too mad to give response to questions like “Don’t you think it is an even more stupid decision to have signed them?”, yet calm enough to consider the potential profit and loss from firing a good portion of them. While getting rid of an employee will save your wage and bonus expenditure on him, termination of a contract before expiration costs you funds for compensation. If you fire an employee, you also fire all his underlings and the underlings of his underlings and those underlings’ underlings’ underlings… An employee may serve in several departments and his (direct or indirect) underlings in one department may be his boss in another department. Is your firing plan ready now?

Input

The input starts with two integers n (0 < n ≤ 5000) and m (0 ≤ m ≤ 60000) on the same line. Next follows n + m lines. The first n lines of these give the net profit/loss from firing the i-th employee individually bi (|bi| ≤ 107, 1 ≤ i ≤ n). The remaining m lines each contain two integers i and j (1 ≤ ij ≤ n) meaning the i-th employee has the j-th employee as his direct underling.

Output

Output two integers separated by a single space: the minimum number of employees to fire to achieve the maximum profit, and the maximum profit.

Sample Input

5 5
8
-9
-20
12
-10
1 2
2 5
1 4
3 4
4 5

Sample Output

2 2

Hint

As of the situation described by the sample input, firing employees 4 and 5 will produce a net profit of 2, which is maximum.

题意:

题目给出N个人,M个直属关系;

N个人每个人都有一个“解雇收益值”,代表公司解雇这个人收益为多少(为负就代表损失);

M个直属关系:(u, v)代表了,解雇u则必须解雇v;

求公司最少解雇几个人之后,可获得最大收益,为多少;

题解:

显然解雇的人满足闭合图关系,而受益最大则是要求最大点权,故本题就是一个最大权闭合子图;

参考http://www.cnblogs.com/dilthey/p/7565206.html即可。

当然,怎么求出被炒的人呢?

在跑完最大流后,残量网络中超级源点s到与其直接相连的点中:

  如果这条边不满流,就属于图S(分割后的两个图中包含超级源点s的那个图),则是属于被解雇的人,就标记;

  如果这条边满流,就属于割集,则这条边的终点不是解雇的人;

然后剩下的,由于图S中,除了与s相连的边权值不为INF外,其他必然为INF,必然不满流,而如果走到了连接t的边,又会变成满流,就会的停下来;

所以只要按着满流与否的条件,DFS下去,不断标记不满流边的终点即可。

AC代码:

 #include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define MAXN 5005
#define MAXM 60005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m;
ll sum;
int cnt;
struct Edge{
int u,v;
ll c,f;
};
struct Dinic
{
int s,t;
vector<Edge> E;
vector<int> G[MAXN];
bool vis[MAXN];
int lev[MAXN];
int cur[MAXN];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int from,int to,ll cap)
{
E.push_back((Edge){from,to,cap,});
E.push_back((Edge){to,from,,});
int m=E.size();
G[from].push_back(m-);
G[to].push_back(m-);
}
bool bfs()
{
memset(vis,,sizeof(vis));
queue<int> q;
q.push(s);
lev[s]=;
vis[s]=;
while(!q.empty())
{
int now=q.front(); q.pop();
for(int i=,_size=G[now].size();i<_size;i++)
{
Edge edge=E[G[now][i]];
int nex=edge.v;
if(!vis[nex] && edge.c>edge.f)
{
lev[nex]=lev[now]+;
q.push(nex);
vis[nex]=;
}
}
}
return vis[t];
}
ll dfs(int now,ll aug)
{
if(now==t || aug==) return aug;
ll flow=,f;
for(int& i=cur[now],_size=G[now].size();i<_size;i++)
{
Edge& edge=E[G[now][i]];
int nex=edge.v;
if(lev[now]+ == lev[nex] && (f=dfs(nex,min(aug,edge.c-edge.f)))>)
{
edge.f+=f;
E[G[now][i]^].f-=f;
flow+=f;
aug-=f;
if(aug==) break;
}
}
return flow;
}
ll maxflow()
{
ll flow=;
while(bfs())
{
memset(cur,,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
}dinic; bool vis[MAXN];
void dfs(int u)
{
for(int i=,_size=dinic.G[u].size();i<_size;i++)
{
Edge& e=dinic.E[dinic.G[u][i]];
if(!vis[e.v] && e.c>e.f)
{
vis[e.v]=;
dfs(e.v);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
sum=;
dinic.init(,n+);
dinic.s=, dinic.t=n+;
for(int i=,w;i<=n;i++)
{
scanf("%d",&w);
if(w>)
{
sum+=(ll)w;
dinic.addedge(dinic.s,i,w);
}
else if(w<) dinic.addedge(i,dinic.t,-w);
}
for(int i=,u,v;i<=m;i++)
{
scanf("%d%d",&u,&v);
dinic.addedge(u,v,INF);
}
//建图完毕
ll max_flow=dinic.maxflow();
//计算出最大流,同时得到残存网络 memset(vis,,sizeof(vis));
dfs(dinic.s);//遍历残存网络,找出被解雇的人
cnt=;
for(int i=;i<=n;i++) if(vis[i]) cnt++; printf("%d %I64d\n",cnt,sum-max_flow);
}

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 | 最大权闭合团

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

  3. poj2987 Firing 最大权闭合子图 边权有正有负

    /** 题目:poj2987 Firing 最大权闭合子图 边权有正有负 链接:http://poj.org/problem?id=2987 题意:由于金融危机,公司要裁员,如果裁了员工x,那么x的下 ...

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

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

  5. poj 2987 Firing【最大权闭合子图+玄学计数 || BFS】

    玄学计数 LYY Orz 第一次见这种神奇的计数方式,乍一看非常不靠谱但是仔细想想还卡不掉 就是把在建图的时候把正权变成w*10000-1,负权变成w*10000+1,跑最大权闭合子图.后面的1作用是 ...

  6. 2018.06.27Firing(最大权闭合子图)

    Firing Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 11558 Accepted: 3494 Description ...

  7. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  8. HDU 3879 Base Station(最大权闭合子图)

    经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...

  9. [BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1497 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以 ...

随机推荐

  1. NetBpm 组织架构(4)

    大牛的杰作,赞一个 转自:NetBPM工作流的架构设计及实现浅析 读前的话:由于本文涉及内容颇多,若有地方读来不很明白,建议先跳过,整体上有个认识后,再回过头来理解.作者认识有限,若有错误,欢迎斧正: ...

  2. OpenGL资料

    苹果官方文档:OpenGL ES for iOS苹果官方文档:OpenGL for OS X OpenGL是源自SGI IRIS GL library,并不是SUN开发的.SGI提供了一个OPENGL ...

  3. C语言中的static关键字

    C语言代码是以文件为单位来组织的,在一个源程序的所有源文件中,一个外部变量(注意不是局部变量)或者函数只能在一个源程序中定义一次,如果有重复定义的话编译器就会报错.伴随着不同源文件变量和函数之间的相互 ...

  4. 存储过程中SELECT INTO的使用

    在MySQL存储过程中使用SELECT …INTO语句为变量赋值: 用来将查询返回的一行的各个列值保存到局部变量中. 要求: 查询的结果集中只能有1行. SELECT col_name[,...] I ...

  5. 【RF库Collections测试】Remove Values From List

    Name:Remove Values From ListSource:Collections <test library>Arguments:[ list_ | *values ]Remo ...

  6. Git 学习笔记--Eclipse Git 插件安装

    http://benjsicam.me/blog/how-to-setup-eclipse-git-plugin-egit-for-github-part-1-tutorial/ http://ben ...

  7. java.util.concurrent.RejectedExecutionException 线程池饱和

    java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPoli ...

  8. linux系统如何操作隐藏文件

    在linux下,以点"."开头命名的文件在系统中被视为隐藏文件.因此,如果想隐藏某个文件或目录,一种简单的办法就是把文件名命名为点开头. 对于目录backcron,可以这样操作隐藏 ...

  9. React Native(十三)——ios键盘挡住textInput

    渐入佳境 用React Native重构的项目也快接近尾声,剩下的就是适配ios的功能了.慢慢地也从中琢磨出了一点门道,于是就遇见了键盘遮挡textInput问题斑斑: 正常页面: android点击 ...

  10. hadoop关联文件处理

    c001.txt ------------------------------ filetype|commid|commname|addressidcomm|1|罗湖小区1|1comm|2|罗湖小区2 ...