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

思路:标准的最大权闭合图,构图:从源点s向每个正收益点连边,容量为收益;从每个负收益点向汇点t连边,容量为收益的相反数;对于i是j的上司,连边i->j,容量为inf。最大收益 = 正收益点权和 - 最小割 = 正收益点权和 - 最大流(胡波涛论文上有证明)。这题的关键是如何在最小割的前提下求出最少的割边数目,可以从源点对残量网络进行一次DFS,每个割都会将源汇隔开,所以从源点DFS下去一定会因为碰到某个割而无法前进,用反证法易知这时遍历过的点数就是S集的最少点数。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define MAXN 5555
#define MAXM 5555555
#define inf 1<<30 struct Edge{
int v,cap,next;
}edge[MAXM]; int n,m,NE,vs,vt,NV,num;
int head[MAXN]; void Insert(int u,int v,int cap)
{
edge[NE].v=v;
edge[NE].cap=cap;
edge[NE].next=head[u];
head[u]=NE++; edge[NE].v=u;
edge[NE].cap=;
edge[NE].next=head[v];
head[v]=NE++;
} int level[MAXN],gap[MAXN];
void bfs(int vt)
{
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int>que;
que.push(vt);
while(!que.empty()){
int u=que.front();
que.pop();
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(level[v]<){
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
}
} int pre[MAXN],cur[MAXN];
long long SAP(int vs,int vt)
{
bfs(vt);
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
long long maxflow=;
int u=pre[vs]=vs,aug=inf;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap>&&level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
aug=min(aug,edge[i].cap);
if(v==vt){
maxflow+=aug;
for(u=pre[v];v!=vs;v=u,u=pre[u]){
edge[cur[u]].cap-=aug;
edge[cur[u]^].cap+=aug;
}
aug=inf;
}
break;
}
}
if(flag)continue;
int minlevel=NV;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap>&&level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==)break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return maxflow;
} bool mark[MAXN];
void dfs(int u)
{
mark[u]=true;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap>&&!mark[v]){
num++;
dfs(v);
}
}
} int main()
{
int u,v,w;
long long sum,ans;
while(~scanf("%d%d",&n,&m)){
NE=;
memset(head,-,sizeof(head));
vs=,vt=n+,NV=n+;
sum=;
for(int i=;i<=n;i++){
scanf("%d",&w);
if(w>){
Insert(vs,i,w);
sum+=w;
}else
Insert(i,vt,-w);
}
while(m--){
scanf("%d%d",&u,&v);
Insert(u,v,inf);
}
ans=sum-SAP(vs,vt);
num=;
memset(mark,false,sizeof(mark));
dfs(vs);
printf("%d %lld\n",num,ans);
}
return ;
}

poj 2987(最大权闭合图+割边最少)的更多相关文章

  1. poj 2987 最大权闭合图

    Language: Default Firing Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 8744   Accept ...

  2. hdu 2987最大权闭合图模板类型题

    /* 最大权闭合图模板类型的题,考验对知识概念的理解. 题意:如今要辞退一部分员工.辞退每个员工能够的到一部分利益(能够是负的),而且辞退员工,必须辞退他的下属.求最大利益和辞退的最小人数. 最大权闭 ...

  3. POJ 2987:Firing(最大权闭合图)

    http://poj.org/problem?id=2987 题意:有公司要裁员,每裁一个人可以得到收益(有正有负),而且如果裁掉的这个人有党羽的话,必须将这个人的所有党羽都裁除,问最少的裁员人数是多 ...

  4. POJ 2987 Firing 网络流 最大权闭合图

    http://poj.org/problem?id=2987 https://blog.csdn.net/u014686462/article/details/48533253 给一个闭合图,要求输出 ...

  5. poj 2987 Firing 最大权闭合图

    题目链接:http://poj.org/problem?id=2987 You’ve finally got mad at “the world’s most stupid” employees of ...

  6. POJ 2987 Firing【最大权闭合图-最小割】

    题意:给出一个有向图,选择一个点,则要选择它的可以到达的所有节点.选择每个点有各自的利益或损失.求最大化的利益,以及此时选择人数的最小值. 算法:构造源点s汇点t,从s到每个正数点建边,容量为利益.每 ...

  7. POJ 2987 Firing(最大权闭合图)

    [题目链接] http://poj.org/problem?id=2987 [题目大意] 为了使得公司效率最高,因此需要进行裁员, 裁去不同的人员有不同的效率提升效果,当然也有可能是负的效果, 如果裁 ...

  8. POJ 2987 Firing(最大流最小割の最大权闭合图)

    Description You’ve finally got mad at “the world’s most stupid” employees of yours and decided to do ...

  9. POJ 3155 Hard Life 最大密度子图 最大权闭合图 网络流 二分

    http://poj.org/problem?id=3155 最大密度子图和最大权闭合图性质很相近(大概可以这么说吧),一个是取最多的边一个是取最多有正贡献的点,而且都是有选一种必须选另一种的限制,一 ...

随机推荐

  1. IFA Basics

    The inverted-F antenna is shown in Figure 1. While this antenna appears to be a wire antenna, after ...

  2. CSS优先级的详细解说

    一.什么是CSS优先级? 所谓CSS优先级,即是指CSS样式在浏览器中被解析的先后顺序. 二.CSS优先级规则 既然样式有优先级,那么就会有一个规则来约定这个优先级,而这个“规则”就是本次所需要讲的重 ...

  3. struts result动态结果集 带参数的结果集

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC     &qu ...

  4. bbc mvn报错

    http://www.cnblogs.com/zhouyalei/archive/2011/11/30/2268606.html

  5. delete与delete [] 真正差别

    我们通常从教科书上看到这种说明: delete 释放new分配的单个对象指针指向的内存 delete[] 释放new分配的对象数组指针指向的内存 那么,依照教科书的理解,我们看下以下的代码: int ...

  6. php.ini配置与中国间隔12小时间设置方法

    打开php.ini 配置文件找到date.timezone把=号后面的参数改成这个date.timezone = Etc/GMT+4即可,这样与中国的时间误差即能达到12小时

  7. MVC数据验证Model Validation

    Required必须项验证属性 [Required] public string FirstName { get; set; } //ID编号 [ScaffoldColumn(false)] [Req ...

  8. FreeSWITCH技巧:notify与message-waiting

    FreeSWITCH技巧:notify与message-waiting @(Freeswitch经验点滴) 现象描述 在客户端登陆抓包时,发现了FreeSWITCH发来的包: NOTIFY sip:9 ...

  9. Jetty - Handler源码分析

    1. 描述 基于Jetty-9.4.8.v20171121. Handler是Jetty服务处理器,用户Server处理HTTP请求. Handler可以做如下处理: (1)完全生成HTTP响应: ( ...

  10. atitit.LimeSurvey 安装 attilax 总结

    LimeSurvey 安装 (OSSEZ) CHS 技术参考, 2011-05-02 Author: YUCHENG HU, HA Websystems, Inc. 备忘 Copyright © HA ...