poj2987 Firing
以前只是A过很简单的最大闭合权像hdu1565之类,完全的最大流模板题。但是都完全不太懂最大闭合权的定义及其用途。
关于最大流的基础知识,大家可以自己网上搜索关键字。有点基础的哥们妹们,推荐看看胡伯涛 《最小割模型在信息学竞赛中的应用》,里面除了很多理论知识以外还有很多不错题集,大家可以练练。
最大闭合权,是最大流一个很经典的应用,关键字:闭合图,最大闭合权。
这种题目表现的模型通常是A-->B-->C,即A事件发生,其后续事件也一定要发生。
如果每个事件发生都有一个效益值的,用最大流算法便可以求出这种效益的最值。
这个题目的另外一个问题是要求删掉的最少点数,乍一看好像很陌生,但是,大家不妨自己举个例子就可以发现这个就是传说中——最简的 、最小割集!
最小割集固然是可能有很多个的,分割的位置便是网络中满流的位置。
这道题求最简的最小割,那就是从源点开始,遍历所有可行边所访问的点集!
帖个水水的代码,希望没有寒碜到大家。WA了n多次,后来发现是计算最大流函数的返回值忘了改成lli。我的钛合金**眼啊!!!!
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long lli;
const int maxn = ;
const int maxe = ;
const lli maxf = 1LL<<;
#define smaller(a,b) ((a)<(b)?(a):(b))
struct edge{
int u,v;
lli c;
edge(int a=,int b=,lli d=){ u=a, v=b, c=d; }
}e[maxe];
int head[maxn];
int next[maxe];
int cnt;
void add(int u,int v,lli c){
e[cnt] = edge(u,v,c);
next[cnt] = head[u], head[u] = cnt++;
//printf("cnt = %d,\t%d --> %d with c = %d, next = %d\n",cnt-1,u,v,c,next[cnt-1]);
e[cnt] = edge(v,u,);
next[cnt] = head[v], head[v] = cnt++;
}
//*****//
int source,sink,maxdep;
int dep[maxn],gap[maxn];
int cur[maxn],trace[maxn],que[maxn],top;
void setGD(){
for(int i=;i<=maxdep;i++) dep[i] = maxdep;
dep[sink] = ;
memset(gap,,sizeof(gap));
gap[dep[sink]] = ;
gap[maxdep] = maxdep;
int front,rear,u,v;
front = rear = ;
que[rear++] = sink;
while(front != rear){
u = que[front++];
if(front >= maxn) front = ;
for(int i=head[u];i!=-;i=next[i]){
v = e[i].v;
if(e[i].c> || dep[v] <= dep[u]+) continue;
dep[v] = dep[u]+;
gap[dep[v]]++;
que[rear++] = v;
if(rear >= maxn) rear = ;
}
}
}
lli maxF(){
setGD();
for(int i=;i<=maxdep;i++) cur[i] = head[i];
int u=source,i;
top = ;
lli flow = ;
while(dep[source] <= maxdep){
if(u == sink){
lli tf = maxf;
int ins;
for(i=;i<top;i++){ //找瓶颈边
if(tf > e[trace[i]].c){
tf = e[trace[i]].c;
ins = i;
}
}
/*
for(i=0;i<top;i++)
printf("%d -> ",e[trace[i]].u);
printf("%d , temp_flow = %d\n",e[trace[top-1]].v,tf);
*/
for(i=;i<top;i++){
e[trace[i]].c -= tf;
e[trace[i]^].c += tf;
}
flow += tf;
u = e[trace[ins]].u, top = ins;
}
if(u != sink && gap[dep[u]-]==) break;
for(i=cur[u];i!=-;i=next[i])
if(e[i].c > && dep[u] == dep[e[i].v] + )
break;
if(i != -) {
trace[top++] = i;
cur[u] = i;
u = e[i].v;
}
else {
int mindep = maxdep;
for(i=head[u];i!=-;i=next[i]){
if(e[i].c > && dep[e[i].v] < mindep)
mindep = dep[e[i].v], cur[u] = i;
}
gap[dep[u]]--;
dep[u] = mindep + ;
gap[dep[u]]++;
if(u != source)
u = e[trace[--top]].u;
}
}
return flow;
}
//**********************//
int visited[maxn];
int value[maxn];
void initial()
{
cnt = ;
memset(head,-,sizeof(head));
memset(visited,,sizeof(visited));
//initial source ,sink and maxdep;
}
int era;
void search(int u){
//cout<<"u = "<<u<<endl;
visited[u] = ;
era++;
for(int i=head[u];i>=;i=next[i])
if(!visited[e[i].v] && e[i].c)
search(e[i].v);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m) != EOF){
lli sum = ;
int u,v,c;
initial();
source=,sink=n+,maxdep=sink+;
for(int i=;i<=n;i++){
scanf("%d",&c);
value[i] = c;
if(c > ) add(source,i,c), sum+=c;
else if(c < ) add(i,sink,-c);
}
for(int i=;i<m;i++)
scanf("%d%d",&u,&v), add(u,v,maxf);
lli ret = maxF();
//if(ret >= sum) puts("0 0"); else {
era = ;
search(source);
cout<<(era-)<<" "<<(sum-ret)<<endl;
//}
}
return ;
}
poj2987 Firing的更多相关文章
- POJ2987 Firing 【最大权闭合图】
POJ2987 Firing Description You've finally got mad at "the world's most stupid" employees o ...
- poj2987 Firing 最大权闭合子图 边权有正有负
/** 题目:poj2987 Firing 最大权闭合子图 边权有正有负 链接:http://poj.org/problem?id=2987 题意:由于金融危机,公司要裁员,如果裁了员工x,那么x的下 ...
- POJ2987 Firing 最大权闭合图
详情请参考http://www.cnblogs.com/kane0526/archive/2013/04/05/3001557.html 值得注意的地方,割边会把图分成两部分,一部分和起点相连,另一部 ...
- poj2987 Firing[最小割]
题目 求选最少点个数的最大权闭合子图.(板子题) 最小割入门题,什么都不想说,丢个别人题解地址就跑. 附加几点个人理解:与s相通的S点集是闭合子图,剩下的与t相通的T点集是其他的.任意一个割都保证了有 ...
- POJ2987:Firing——题解
http://poj.org/problem?id=2987 题目大意: 炒掉一个人能够获得b收益(b可以<0),但是炒掉一个人必须得炒掉他的下属(然后继续递归). 求最大收益和此时最小裁员. ...
- 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 (最小割-最大权闭合子图)
裁员 [问题描述] 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误.给出每个人的贡献值和 ...
- poj Firing(最大重量封闭图)
Firing 题目: 要解雇一些人,而解雇的这些人假设人跟他有上下级的关系,则跟他有关系的人也要一起解雇.每一个人都会创造一定的价值,要求你求出在最大的获利下.解雇的人最小. 算法分析: 在这之前要知 ...
- POJ 2987 Firing (最大权闭合图)
Firing Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 12108 Accepted: 3666 Descript ...
随机推荐
- 得到当前网址的域名 ASP.NET
HttpContext.Current.Request.Url.Host.ToString(); http://"是协议名 "www.test.com"是域名 " ...
- java中文乱码解决之道(一)—–认识字符集
原文出处:http://cmsblogs.com/?p=1395 沉寂了许久(大概有三个多月了吧),LZ“按捺不住”开始写博了! java编码中的中文问题是一个老生常谈的问题了,每次遇到中文乱码LZ要 ...
- AngularJs(三) deployd 服务的使用
使用服务建立数据 在AngularJS(二)中,我搭建好了deployd服务,现在启动服务,创建正在的数据(开始是使用模拟数据),使用cmd命令 一.开启Mongodb数据. 贴图: 二:测试是否正常 ...
- 业务需求那些事,使用WCF如何实现业务需求!
最近遇到一个新项目,需要与硬件结合,进行读取信息并保存在数据库中.业务要求也在昨天发布一个问题,当然感谢许多园内的朋友出谋划策,截图有真相! 关于这个问题,我做了如下假设.目前处于测试状态,代码比较简 ...
- UIScrollView中添加一个视图,实现让其始终固定在某个位置
ScrollView中添加一个视图,实现让其始终固定在某个位置,如最底部的位置.方法是自定义一个继承UIScrollView,重写它的layoutSubviews方法.代码如下: #import &q ...
- 剑指offier77页
/* * 输入字母判断第几列 */ import java.util.Scanner; public class JudgeClumns { public static void main(Strin ...
- EC读书笔记系列之2:条款4 确定对象被使用前已先被初始化
条款4:确定对象被使用前已先被初始化 记住: ★为内置对象进行手工初始化,因为C++不保证初始他们 ★构造函数最好使用初始化列表,而不要在构造函数本体内使用赋值操作.初始化列表列出的成员变量,其排列次 ...
- Python进阶之map()、reduce()、filter()
map()函数 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB",&q ...
- 利用border和伪类画出三角形 ps:好久没写博客了。。。
有一个半月没有写博客了,这段时间,小哥我经历了自入行前端最为黑暗的时期,迷茫,空虚,不想写代码,不想做研究了.连打游戏都没有兴趣,如同行尸走肉一般.还好,毕业论文的初稿完成后,整个时间段最恶心最难熬的 ...
- hdu 4634 Swipe Bo bfs+状态压缩
题目链接 状态压缩记录当前拿到了哪些钥匙, 然后暴力搜索. 搞了好几个小时, 一开始也不知道哪里错了, 最后A了也不知道一开始哪里有问题. #include <iostream> #inc ...