题意:

     公司要裁员,每个员工被裁掉之后都会有一定的收益(正或者负),有一些员工之间有限制关系,就是裁掉谁之前必须要先裁掉另一个人,问公司的最大收益和最大收益前提下的最小裁员人数?

思路:

      收益有正、有负,员工之间有限制关系,那么是不是瞬间就想到了杭电的那个通讯塔的那么题目,虽然那个是最大点权独立集,而这二个是最大权闭包,但是我感觉两者想法一样,只不过中间是通过一些转换了,这个题有个特别的地方,就是输出最小裁员人数,这个还真不知道怎么弄,然后在网上看了下,说是在残余网络上直接从起点开始搜索,能走到几个就是几,写到是很好写,关键是理解为什么?这个据说论文上有,我说下我的理解,我感觉可能是这样,ss-a-b-tt,如果跑完之后ss-a还有流量会怎样?是不是还有流量就证明挣的钱比花的钱多,那么我们就删除点a,b就行了,把问题复杂化也一样,ss-a-b-tt
ss-a-c-tt ,就是说删除a之前要删除b,c才行,如果ss-a还有流量就证明ss-a > (b->tt)+(c->tt)那么删除他们三个是最优的......

#include<queue>
#include<stdio.h>
#include<string.h> #define N_node 5500
#define N_edge 150000
#define INF 0x3f3f3f3f3f3f3f3f using namespace std; typedef struct
{
int to ,next;
long long cost;
}STAR; typedef struct
{
int x ,t;
}DEP; DEP xin ,tou;
STAR E[N_edge];
int list[N_node] ,listt[N_node] ,tot;
int deep[N_node]; void add(int a ,int b ,long long c)
{
E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot; E[++tot].to = a;
E[tot].cost = 0;
E[tot].next = list[b];
list[b] = tot;
} long long minn(long long x ,long long y)
{
return x < y ? x : y;
} bool BFS_Deep(int s ,int t ,int n)
{
memset(deep ,255 ,sizeof(deep));
xin.x = s ,xin.t = 0;
deep[xin.x] = xin.t;
queue<DEP>q;
q.push(xin);
while(!q.empty())
{
tou = q.front();
q.pop();
for(int k = list[tou.x] ;k ;k = E[k].next)
{
xin.x = E[k].to;
xin.t = tou.t + 1;
if(deep[xin.x] != -1 || !E[k].cost)
continue;
deep[xin.x] = xin.t;
q.push(xin);
}
}
for(int i = 0 ;i <= n ;i ++)
listt[i] = list[i];
return deep[t] != -1;
} long long DFS_Flow(int s ,int t ,long long flow)
{
if(s == t) return flow;
long long nowflow = 0;
for(int k = listt[s] ;k ;k = E[k].next)
{
listt[s] = k;
int to = E[k].to;
long long c = E[k].cost;
if(deep[to] != deep[s] + 1 || !c)
continue;
long long tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));
nowflow += tmp;
E[k].cost -= tmp;
E[k^1].cost += tmp;
if(nowflow == flow) break;
}
if(!nowflow) deep[s] = 0;
return nowflow;
} long long DINIC(int s ,int t ,int n)
{
long long Ans = 0;
while(BFS_Deep(s ,t ,n))
{
Ans += DFS_Flow(s ,t ,INF);
}
return Ans;
} int SS;
int mark[N_node];
void DFS(int s)
{
mark[s] = 1;
for(int k = list[s] ;k ;k = E[k].next)
{
if(!mark[E[k].to] && E[k].cost)
{
SS ++;
DFS(E[k].to);
}
}
return ;
} int main ()
{
int n ,m ,i ,a ,b;
long long c ,S;
while(~scanf("%d %d" ,&n ,&m))
{
int ss = 0 ,tt = n + 1;
memset(list ,0 ,sizeof(list));
tot = 1;
for(S = 0 ,i = 1 ;i <= n ;i ++)
{
scanf("%lld" ,&c);
c > 0 ? add(ss ,i ,c) : add(i ,tt ,-c);
if(c > 0) S += c;
}
for(i = 1 ;i <= m ;i ++)
{
scanf("%d %d" ,&a ,&b);
add(a ,b ,INF);
}
S -= DINIC(ss ,tt ,tt);
memset(mark ,0 ,sizeof(mark));
SS = 0;
DFS(ss);
printf("%d %lld\n" ,SS ,S);
}
return 0;
}

poj2987最大权闭包(输出最少建塔个数)的更多相关文章

  1. hdu4971 流-最大权闭包

    题意:       给了一些任务,然后给了一些完成某些任务的限制,然后又给了限制之间的拓扑关系,最后问你最大收益. 思路:       很直白,就是流的一个应用,最大权闭包,没涉及到什么想法的地方,建 ...

  2. HDU5772 String problem 最大权闭合图+巧妙建图

    题意:自己看吧(不是很好说) 分析: 网络流:最大权闭合子图. 思路如下: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得 ...

  3. hdu 5256 最少修改多少个数 能使原数列严格递增 (LIS)

    Problem Description我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增.其中无论是修改前还是修改后,每个元素都必须是整数. 请输出最少需要修改多少 ...

  4. 554. Brick Wall最少的穿墙个数

    [抄题]: There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. ...

  5. 华为OJ平台——输出最小的k个数

    输入n个整数,输出其中最小的k个. 详细描述: 接口说明 原型: bool GetMinK(unsignedint uiInputNum, int *pInputArray, unsignedint ...

  6. 神经网络结构设计指导原则——输入层:神经元个数=feature维度 输出层:神经元个数=分类类别数,默认只用一个隐层 如果用多个隐层,则每个隐层的神经元数目都一样

    神经网络结构设计指导原则 原文   http://blog.csdn.net/ybdesire/article/details/52821185   下面这个神经网络结构设计指导原则是Andrew N ...

  7. [LeetCode] 871. Minimum Number of Refueling Stops 最少的加油站个数

    A car travels from a starting position to a destination which is target miles east of the starting p ...

  8. ZOJ-2338 The Towers of Hanoi Revisited 输出汉诺塔的最优解移动过程

    题意:给定N(1<= N <=64)个盘子和M(4<= M <= 65)根柱子,问把N个盘子从1号柱子移动到M号柱子所需要的最少步数,并且输出移动过程. 分析:设f[i][j] ...

  9. poj 2392 建塔(多重背包+不定上界)

    http://blog.csdn.net/libin56842/article/details/9492351 这次比较理解那个!dp[j]是为了什么,因为是滚动数组,没有这个的话used那边会出问题 ...

随机推荐

  1. CCF(公共钥匙盒):思维+模拟

    公共钥匙盒 201709-2 这题的思路一开始不是很清晰,一开始想用贪心去做.但是发现按照题目的思路不对.所以这里采用的是类似于多项式的加减的处理. #include<iostream> ...

  2. Linux速通 大纲

    1.Linux操作系统安装及初始化配置(熟悉) 2.Linux操作系统目录组成结构及文件级增删改查操作(重点) 3.Linux操作系统用户.权限管理(重点) 4.开源软件及Linux下软件包的管理(重 ...

  3. 技术基础 | 在Apache Cassandra中改变VNodes数量的影响

    Apache Cassandra中num_tokens的默认值在4.0版本中将会有变化!这看起来好像只是在CHANGES.txt文件中做了个小小的改动,但实际上这个改动将会对集群的日常运维有着深远的影 ...

  4. 爬虫必知必会(5)_scrapy框架_基础

    一.移动端数据的爬取 基于某一款抓包工具,fiddler,青花瓷,miteproxy fillder进行一个基本的配置:tools->options->connection->all ...

  5. Spring Boot 启动过程

    一切从SpringApplication.run()开始,最终返回一个ConfigurableApplicationContext 构造了一个SpringApplication对象,然后调用它的run ...

  6. ASP.NET跨域访问解决

    第一种: step1:添加引用(搜索CORS) step2: App_Start/WebApiConfig.cs中添加配置 step3: 在控制器中添加特性 第二种: 在App_Start/WebAp ...

  7. 阿里二面:什么是mmap?

    平时在面试中你肯定会经常碰见的问题就是:RocketMQ为什么快?Kafka为什么快?什么是mmap? 这一类的问题都逃不过的一个点就是零拷贝,虽然还有一些其他的原因,但是今天我们的话题主要就是零拷贝 ...

  8. js_笔记_8月7日记录_活动对象_作用域链_按值传递

    活动对象:简单说就是这个函数的参数和显示声明的变量或函数. 函数内接受的参数实际是创建了一个局部变量:[形参名] = [传进来的值],js的函数传参只传值. 作用域链:执行流进入一个函数,会先创建出作 ...

  9. OpenGL光照计算中法线矩阵原理及推到过程

    问题起源 在计算漫反射关照时,需要用到法线,通过法线和光线的点乘值,计算漫反射的产生的光线强度,所以需要从顶点着色器中将法线数据传递到片源着色器中,但是片源着色器中的顶点坐标是经过了模型矩阵变化过的世 ...

  10. java例题_34 用指正对三个数排序

    1 /*34 [程序 34 三个数排序] 2 题目:输入 3 个数 a,b,c,按大小顺序输出. 3 程序分析:利用指针方法. 4 */ 5 6 /*分析 7 * 指针方法的本质是按地址传值,将a,b ...