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 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以 ...
随机推荐
- 第四章 TCP粘包/拆包问题的解决之道---4.2--- 未考虑TCP粘包导致功能异常案例
4.2 未考虑TCP粘包导致功能异常案例 如果代码没有考虑粘包/拆包问题,往往会出现解码错位或者错误,导致程序不能正常工作. 4.2.1 TimeServer 的改造 Class : TimeServ ...
- Spring JDBC入门
Spring将替我们完成所有使用JDBC API进行开发的单调乏味的.底层细节处理工作. 操作JDBC时Spring可以帮我们做这些事情: 定义数据库连接参数,打开数据库连接,处理异常,关闭数据库连接 ...
- bat批处理文件按顺序执行exe
start /d "deepstream.io-windows-3.1.0" deepstream.exe rem 等待1秒钟 choice /t 1 /d y /n cd &qu ...
- React Native(十三)——ios键盘挡住textInput
渐入佳境 用React Native重构的项目也快接近尾声,剩下的就是适配ios的功能了.慢慢地也从中琢磨出了一点门道,于是就遇见了键盘遮挡textInput问题斑斑: 正常页面: android点击 ...
- pgAdmin III 单表数据的导出导入
看了好几种方法也试验了几次都没成功,终于找到一种比较简单的试验成功的方法,记录下来留作备份. 将表testTable_1里的数据导入到表testTable_2里,如图: 两表的结构相同.表testTa ...
- Linux平台下mysql的ODBC配置方法
在安装配置之前, 需要先大概了解一下MyODBC的架构. MyODBC体系结构建立在5个组件上,如下图所示: Driver Manager: 负责管理应用程序和驱动程序间的通信, 主要功能包括: 解析 ...
- 【Linux】`ImportError: No module named '_tkinter'
在centos7 系统下,导入matplotlib时,出现ImportError: No module named '_tkinter'的错误 首先使用以下命令查看模块是否存在 yum list in ...
- Linux(Ubuntu) 下如何解压 .tar.gz 文件
在终端输入以下命令即可解压: tar -zxvf YOUR_FILE_NAME.tar.gz 如果出现“权限不够”的错误提示,在命令前加上 sudo ,即 sudo tar -zxvf YOUR_FI ...
- IPhoneX网页布局 全屏布局(转)
IPhoneX全面屏是十分科技化的,但是由于其圆角和摄像头刘海位置以及操控黑条的存在使得我们需要去对其样式做一些适配,没有X的同学可以开启 Xcode 9 的iPhone X 模拟器作为学习和调试. ...
- redhat vi 命令
转载:http://www.cnblogs.com/zhanglong0426/archive/2010/10/07/1845268.html http://blog.sina.com.cn/s/bl ...