最大权闭合图

Posted chiarochinoful

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大权闭合图相关的知识,希望对你有一定的参考价值。

前置芝士:最大流最小割

一. 啥是闭合图

一件事件x发生需要一个条件:

1. y事件已经发生

2. z事件已经发生

对于这样的依赖关系 , 我们可以用闭合来来描述或者解决

有向图的闭合图(closure)(来源于 胡伯涛《最小割模型在信息学竞赛中的应用》 论文 )

技术图片

物理意义:事物间依赖关系:一个事件要发生 , 她需要的所有前提也都一定发生

最大权闭合图是点权最大的闭合图

例题:[NOI2006]最大获利

技术图片

 一道求最大权闭合图的题

构图:

建源点S, 汇点T

将源点S与正权点连边 , 容量是点权

将汇点T与负权点连边 , 容量是点权

将题目描述的边连上 , 容量是无限大

 

解决:

闭合图的权为所有正权点减去该图中割的容量

技术图片

那么 , 很显然割越小答案越大

所以就要去求最小鸽 , 也就是最大流

 这样 , 那道NOI题也就好做了

  1 #include<cstdio>
  2 #include<queue>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<iostream>
  6 #include<algorithm>
  7 #define APART puts("----------------------")
  8 #define debug 1
  9 #define FILETEST 0
 10 #define inf 120010
 11 #define ll long long
 12 #define ha 998244353
 13 #define INF 0x7fffffff
 14 #define INF_T 9223372036854775807
 15 #define DEBUG printf("%s %d\\n",__FUNCTION__,__LINE__)
 16 
 17 namespace chino
 18 
 19 inline void setting()
 20 #if FILETEST
 21     freopen("test.in", "r", stdin);
 22     freopen("test.me.out", "w", stdout);
 23 #endif
 24     return;
 25 
 26 
 27 inline int read()
 28     char c = getchar(), up = c; int num = 0;
 29     for(; c < 0 || c > 9; up = c, c = getchar());
 30     for(; c >= 0 && c <= 9; num = (num << 3) + (num << 1) + (c ^ 0), c = getchar());
 31     return  up == - ? -num : num;
 32 
 33 
 34 int n, m;
 35 int S, T;
 36 int maxflow, anssum;
 37 int cntE = -1;
 38 int head[inf];
 39 int cur[inf];
 40 int dep[inf];
 41 struct Edge
 42     int to;
 43     int flow;
 44     int next;
 45 e[inf << 1];
 46 std::queue <int> Q;
 47 
 48 inline void AddEdge(int from, int to, int flow)
 49     ++cntE;
 50     e[cntE].to = to;
 51     e[cntE].flow = flow;
 52     e[cntE].next = head[from];
 53     head[from] = cntE;
 54     return;
 55 
 56 
 57 inline bool BFS(int s, int t)
 58     memset(dep, -1, sizeof dep);
 59     memcpy(cur, head, sizeof cur);
 60     while(!Q.empty())
 61         Q.pop();
 62     Q.push(s);
 63     dep[s] = 0;
 64     while(!Q.empty())
 65         int x = Q.front();
 66         Q.pop();
 67         for(int i = head[x]; i ^ -1; i = e[i].next)
 68             int y = e[i].to;
 69             if(dep[y] == -1 && e[i].flow)
 70                 dep[y] = dep[x] + 1;
 71                 Q.push(y);
 72             
 73         
 74     
 75     return dep[t] ^ -1;
 76 
 77 
 78 int DFS(int s, int limit)
 79     if(limit == 0 || s == T)
 80         return limit;
 81     int flow = 0;
 82     int f = 0;
 83     for(int i = cur[s]; i ^ -1; i = e[i].next)
 84         cur[s] = i;
 85         int to = e[i].to;
 86         int Min = std::min(limit, e[i].flow);
 87         if(dep[to] == dep[s] + 1 && (f = DFS(to, Min)))
 88             flow += f;
 89             limit -= f;
 90             e[i].flow -= f;
 91             e[i ^ 1].flow += f;
 92             if(limit == 0)
 93                 break;
 94         
 95     
 96     return flow;
 97 
 98 
 99 inline void dinic(int s, int t)
100     while(BFS(s, t))
101         maxflow += DFS(s, INF);
102     return;
103 
104 
105 inline int main()
106     memset(head, -1, sizeof head);
107     n = read();
108     m = read();
109     S = n + m + 1;
110     T = n + m + 2;
111     for(int i = 1; i <= n; i++)
112         int tmp = read();
113         AddEdge(i + m, T, tmp);
114         AddEdge(T, i + m, 0);
115     
116     for(int i = 1; i <= m; i++)
117         int a = read();
118         int b = read();
119         int v = read();
120         anssum += v;
121         AddEdge(i, a + m, INF >> 1);
122         AddEdge(a + m, i, 0);
123         
124         AddEdge(i, b + m, INF >> 1);
125         AddEdge(b + m, i, 0);
126         
127         AddEdge(S, i, v);
128         AddEdge(i, S, 0);
129     
130     dinic(S, T);
131     printf("%d\\n", anssum - maxflow);
132     return 0;
133 
134 
135 //namespace chino
136 
137 int main()return chino::main();

 例题2:luogu太空飞行计划问题

题意重点:每个仪器在购买后可以用无限次

 

不难看出也是一道最大权闭合图题 , 所以建图就是如之前一样了

那么怎么样输出方案呐

因为最小鸽C[S,T]将图G分成没有交的两个点集S和T

而答案就是集合S里所有的点

 

并不是说一个实验收入是负数就不要做这个实验

如题目样例

有些实验可能是给后面的实验买仪器 , 可能这个实验不赚钱 , 但是后面的实验不需要买仪器了 , 那这个方案可能更优

以上是关于最大权闭合图的主要内容,如果未能解决你的问题,请参考以下文章

最大权闭合图

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

[luoguP2762] 太空飞行计划问题(最大权闭合图—最小割—最大流)

hdu 3917 修路与公司 最大权闭合图 好题

POJ 2987 Firing (最大权闭合图)

hdu 4971/ 2014多校/最大权闭合图