POJ 2987 Firing 最大权闭合子图
来源:互联网 发布:优化营商环境建议 编辑:程序博客网 时间:2024/05/21 17:21
题意:有N个人,M个人的前后上下级关系。当你解雇一个人时,他的下级会被全部解雇。解雇每个人有收益,可能为正或为负。求出最大收益。同时求出裁员的最小人数。
思路:问题中出现了前后依赖关系,我们很容易想到最大权闭合子图。直接利用最大权闭合子图模型,我们可以求出最大的收益。现在问题是如何求出最小的裁员人数。
我们先考虑为什么会出现裁员的最小人数。因为,虽然最小割的容量是唯一的,但是,可能因为流网络结构的不同,导致最小割的边的集合是不唯一的,这就导致我们可以选择多种st割,让位于S集合的点的数目不同,从而出现了最小的S集合。
为了求出最小的S的集合,我们从源点S开始进行搜索,一遇到不位于残留网络的边,就不再继续向下搜索,即认为后面的点都和T相连,即最大化被留下的人。这样我们就可以最小的S的集合。BFS和DFS都可以。
代码如下:
<span style="font-size:12px;">#include <cstdio>#include <algorithm>#include <cstring>using namespace std;typedef long long ll;struct edge{ int from,to; ll cap,flow; edge(int u =0,int v =0,ll c=0LL,ll f=0LL):from(u),to(v),cap(c),flow(f){}};struct ISAP{ static const ll INF = 0x3f3f3f3f3f3f3f3f; static const int MAX = 100010;//2倍的边的大小 int head[MAX];//每个节点对应链表的开始位置 int next[MAX];//链表的下一个节点在edges数组的位置 int tot;//edges数组的大小 edge edges[MAX];//储存边的数组 int que[MAX],front,tail;//队列,保存节点 int d[MAX];//距离标号 bool vis[MAX];//访问标记 int num[MAX];//gap优化 int pre[MAX];//增广路中,节点X的前面一个弧的标号 int cur[MAX];//对于每个节点的,处理的当前弧。 int s,t,n;//s源点标号,t汇点标号,n节点总数 int cnt; void init(int n){ this->n = n;//注意此处的下标问题 memset(head,-1,sizeof(int)*(n+1)); tot = 0;// } void addedge(int from,int to, ll cap){ edges[tot] = edge(from,to,cap,0); next[tot] = head[from], head[from] = tot++; edges[tot] = edge(to,from,0,0); next[tot] = head[to],head[to] = tot++; } void bfs(){ memset(vis,0,sizeof(vis)); front = tail = 0; d[t] = 0; vis[t] = true; que[tail++] = t; while(front < tail){ int u = que[front++]; for(int v = head[u]; v != -1; v = next[v]){ edge & e = edges[v^1]; if(e.cap > e.flow && !vis[e.from]){//对处于残余网络中的弧且没访问过的节点处理 d[e.from] = d[u] + 1; vis[e.from] = true; que[tail++] = e.from; } } } } ll augment(){ int x = t; ll a = INF; while(x != s){ edge& e = edges[pre[x]]; a = min(a,e.cap - e.flow); x = e.from; } x = t; while(x != s){ edges[pre[x]].flow += a; edges[pre[x]^1].flow -= a; x = edges[pre[x]].from; } return a; } ll maxflow(int s, int t){ this->s = s, this->t = t; memset(num,0,sizeof(num)); ll flow = 0LL; bfs(); for(int i = 0; i < n; ++i){//注意此处的下标问题 num[d[i]]++; cur[i] = head[i]; } int x = s; while(d[s] < n){ if(x == t){ flow += augment(); x = s; } bool ok = false; for(int &v = cur[x]; v != -1; v = next[v]){ edge& e = edges[v]; if(e.cap > e.flow && d[x] == d[e.to] + 1){ ok = true; pre[x = e.to] = v; break; } } if(!ok){ int m = n - 1; for(int v = head[x]; v != -1; v = next[v]){ edge & e = edges[v]; if(e.cap > e.flow) m = min(m,d[e.to]); } if(--num[d[x]] == 0) break; num[d[x]=m+1]++; cur[x] = head[x]; if(x != s) x = edges[pre[x]].from; } } return flow; } void dfs(int u){ vis[u] = true; for(int v = head[u]; ~v; v = next[v]){ edge & e = edges[v]; if(e.cap > e.flow &&!vis[e.to]){ cnt++; dfs(e.to); } } } int mincut(){ memset(vis,0,sizeof(vis)); cnt = 0; dfs(s); return cnt; }} solver;const ll INF = 0x3f3f3f3f3f3f3f3f;int T;int n,m;int s,t;ll pro;int sum;int x,y;int main(void){ //freopen("input.txt","r",stdin); ll sum = 0LL; scanf("%d %d", &n, &m); s = 0, t = n + 1; solver.init(n + 2); for(int i = 1 ; i <= n; ++i){ scanf("%lld", &pro); if(pro > 0){ solver.addedge(s,i,pro); sum += pro; } else solver.addedge(i,t,-pro); } for(int i = 0 ; i < m; ++i){ scanf("%d %d", &x, &y); solver.addedge(x,y,INF); } ll ans2 = solver.maxflow(s,t); int ans1 = solver.mincut(); printf("%d %lld\n",ans1,sum - ans2); return 0;}</span>
0 0
- POJ 2987 Firing (最大权闭合子图Dinic)
- 【POJ】2987 Firing 最大权闭合子图
- POJ 2987 Firing 最大权闭合子图
- poj 2987 Firing 最大权闭合子图
- poj 2987 Firing (最大权闭合子图)
- POJ 2987 Firing 最大权闭合子图
- poj 2987 Firing 最大权闭合子图
- POJ 2987 Firing 最小割(最大权闭合子图)
- POJ 2987 Firing(最大权闭合子图)
- poj 2987 Firing (最大权闭合子图)
- poj 2987 Firing 最大权闭合子图
- 最大权闭合子图(poj 2987 Firing)
- poj 2987 Firing ------最大权闭合图
- poj 2987 Firing(最大权闭合图)
- POJ 2987 Firing (最大权闭合图)
- POJ 2987 Firing 最大权闭合图
- poj 2987 Firing 最大权闭合图
- POJ 2987 Firing 最大权闭合图
- ZJU 3811 - Untrusted Patrol(DFS)
- xUtils的HTTP整理
- VI 编辑器(Linux)
- wsimport根据服务端的webservice生成客户端代码
- 自考《数据库系统原理》(8)之Power Builder 9.0的简介及应用
- POJ 2987 Firing 最大权闭合子图
- myeclipse 10安装jdbpm4 报错解决方案
- kmp 算法导读
- 并发编程--在执行器中控制任务的完成
- Java 连接Sql server数据库 组件模型
- apue 第五章 标准i/o库
- HDOJ 题目2824 The Euler function(欧拉函数)
- fatal error: 'HIToolbox/HIToolbox.h' file not found #import <HIToolbox/HIToolbox.h>
- 一个简单的Delphi与go lang通讯的例子