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 ...
随机推荐
- $(window).width() is not a function
昨天在帮同事调试JS的时候,FF报错了,$(window).width() is not a function.我以前也是这么用的,都没问题,为什么现在就报错了呢? 这是因为jQuery用" ...
- React系列(一):React入门
React简介 1.由来 React是有Facebook开发出来用于构建前端界面的JS组件库,由于其背后的强大背景,使得这款库在技术开发上完全没有问题. 2.React的优势 解决大规模项目开发中数据 ...
- Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置
参考数据库链接串: <add key="data" value="server=192.168.1.123; Port=3306; uid=root; pwd=ro ...
- JSEL 表达式
JSTL标签库的使用是为类弥补html表的不足,规范自定义标签的使用而诞生的.在告别modle1模式开发应用程序后,人们开始注重软件的分层设计,不希望在jsp页面中出现java逻辑代码,同时也由于自定 ...
- 在Linux下如何用Shell脚本读写XML?现有一个config.xml(转)
在Linux下如何用Shell脚本读写XML?现有一个config.xml <?xml version="1.0" encoding="UTF-8"?&g ...
- 【codevs】2292图灵机游戏
题 Shadow最近知道了图灵机是什么(Shadow:就是一行格子和一个机器头移来移去的呗!),于是他突发奇想,创造了一个新游戏——“图灵机游戏”(Shadow:好听吧?). 游戏规则如下: 在一条长 ...
- VC/MFC使用OLE操作 EXCEL
1.VC插入sheet页到指定位置 插入sheet的函数用 sheets.Add(Before, After,Count,Type) 四个参数含义如下: 四个const VARIANT: ...
- java与javac命令笔记
Java对待.java文件与.class文件是有区别的.对.java文件可以直接指定路径给它,而java命令所需的.class文件不能出现扩展名,也不能指定额外的路径给它,对于Java所需的.clas ...
- [一个经典的多线程同步问题]解决方案二:Event事件
使用关键段来解决经典的多线程同步互斥问题,由于关键段的“线程所有权”特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题. 首先介绍下如何使用事件.事件E ...
- 通过innerHTML简化脚本
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&q ...