POJ 2987 - Firing - [最大权闭合子图]
题目链接: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 ≤ i, j ≤ 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
题意:
题目给出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 - [最大权闭合子图]的更多相关文章
- poj 2987 Firing 最大权闭合图
题目链接:http://poj.org/problem?id=2987 You’ve finally got mad at “the world’s most stupid” employees of ...
- POJ 2987 Firing | 最大权闭合团
一个点带权的图,有一些指向关系,删掉一个点他指向的点也不能留下,问子图最大权值 题解: 这是最大权闭合团问题 闭合团:集合内所有点出边指向的点都在集合内 构图方法 1.S到权值为正的点,容量为权值 2 ...
- poj2987 Firing 最大权闭合子图 边权有正有负
/** 题目:poj2987 Firing 最大权闭合子图 边权有正有负 链接:http://poj.org/problem?id=2987 题意:由于金融危机,公司要裁员,如果裁了员工x,那么x的下 ...
- 【POJ 2987】Firing (最小割-最大权闭合子图)
裁员 [问题描述] 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误.给出每个人的贡献值和 ...
- poj 2987 Firing【最大权闭合子图+玄学计数 || BFS】
玄学计数 LYY Orz 第一次见这种神奇的计数方式,乍一看非常不靠谱但是仔细想想还卡不掉 就是把在建图的时候把正权变成w*10000-1,负权变成w*10000+1,跑最大权闭合子图.后面的1作用是 ...
- 2018.06.27Firing(最大权闭合子图)
Firing Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 11558 Accepted: 3494 Description ...
- BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...
- HDU 3879 Base Station(最大权闭合子图)
经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...
- [BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1497 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以 ...
随机推荐
- Mybatis -- 批量更新 -- updateBatch
mysql数据库配置: 数据库连接必须配置:&allowMultiQueries=true并且‘&’ 用&替换 jdbc.url=jdbc:mysql://192.168.10 ...
- 一段代码让DedeCMS完美兼容PHP5.4
DedeCMS V5.7版本,在本地部署后,正确登录后台的情况下页面没有任何输出和显示(错误登录或密码错误时才有显示),也没有报错.进到脚本调试,发现问题出在userLogin类所在的脚本userlo ...
- eclipse下编译cocos2dx 3.0
先给自己科普一下, android sdk 是给java开发者用的, 咱C++开发者用的是android ndk, 所以就是使用ndk来编译cocos2dx程序了 使用命令行创建一个项目, 我这里创 ...
- 错误 error C2678: 二进制“<”: 没有找到接受“const card”类型的左操作数的运算符(或没有可接受的转换)
错误出现的地方如下 而我又重载了<运算符,但是我没有将<运算符重载函数定义成const类型,此处是const _Ty&,不可以调用非const成员函数 而且,一般而言,像<, ...
- python线程池(threadpool)
一.安装 pip install threadpool 二.使用介绍 (1)引入threadpool模块 (2)定义线程函数 (3)创建线程 池threadpool.ThreadPool() (4)创 ...
- 【GIS】WGS84与Web墨卡托理解(转)
坐标系 · WGS84,地理坐标系,单位度,在三维上可以很好的展示全球的数据,但在二维上显示时在高纬度地区变形较大,另由于WGS84坐标系与CGCS2000坐标系差异很小,所以WGS84坐标系在Web ...
- unity2017.4.0f1使用AS3.0的AndroidSDK遇到的问题
原因: Unity 在编译时会调用 Android SDK tools 中的 android 命令,而在新版本的 Android SDK tools 中,android这个命令已经废弃了,导致 Uni ...
- android新建的项目界面上没有显示怎么办?
看log也没有说明具体情况? 一翻折腾在清单文件里加了权限就好了!!!
- 《转载》Python3安装Scrapy
运行平台:Windows Python版本:Python3.x IDE:Sublime text3 转载自:http://blog.csdn.net/c406495762/article/detail ...
- SqlServer 连接远程服务器数据库 实现跨服务器联合查询
第一种: exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' exec sp_addlinkedsrvlogin 'IT ...