网络流五·最大权闭合子图 HihoCoder - 1398

Posted yijiull

tags:

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

网络流五·最大权闭合子图

 HihoCoder - 1398 

 

技术分享
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxv = 410;
  4 const int maxe = 40210;
  5 const int inf = 0x3f3f3f3f;
  6 struct Edge{
  7     int u, v, nex;
  8     int cap, flow;
  9     Edge(int u=0, int v=0, int nex=0, int cap=0, int flow=0):
 10         u(u), v(v), nex(nex), cap(cap), flow(flow){}
 11 }e[maxe<<1];
 12 int head[maxv];
 13 int cnt;
 14 void init(){
 15     memset(head, -1, sizeof(head));
 16     cnt = 0;
 17 }
 18 
 19 void add(int u, int v, int cap){
 20     e[cnt] = Edge(u, v, head[u], cap, 0);
 21     head[u] = cnt++;
 22     e[cnt] = Edge(v, u, head[v], 0, 0);
 23     head[v] = cnt++;
 24 }
 25 
 26 int d[maxv], num[maxv], cur[maxv], p[maxv];
 27 int vis[maxv];
 28 int S, T;
 29 int N;
 30 
 31 void bfs(){
 32     memset(d, -1, sizeof(d));
 33     memset(vis, 0, sizeof(vis));
 34     queue<int> q;
 35     q.push(T);
 36     vis[T] = 1;
 37     while(!q.empty()){
 38         int u = q.front();
 39         q.pop();
 40         for(int i = head[u]; ~i; i = e[i].nex){
 41             int id = i&(-2);  //正边
 42             int v = e[id].u;
 43             if(!vis[v] && e[id].cap > e[id].flow){
 44                 vis[v] = 1;
 45                 d[v] = d[u] + 1;
 46                 q.push(v);
 47             }
 48         }
 49     }
 50 }
 51 
 52 int augment(){
 53     int u = T;
 54     int a = inf;
 55     while(u!=S){
 56         int id = p[u];
 57         a = min(a, e[id].cap - e[id].flow);
 58         u = e[id].u;
 59     }
 60     u = T;
 61     while(u!=S){
 62         int id = p[u];
 63         e[id].flow += a;
 64         e[id^1].flow -= a;
 65         u = e[id].u;
 66     }
 67     return a;
 68 }
 69 
 70 int ISAP(){
 71     bfs();
 72     int flow = 0;
 73     memset(num, 0, sizeof(num));
 74     for(int i = 0; i < N; i++){
 75         cur [i] = head[i];
 76         if(~d[i]) num[d[i]]++;
 77     }
 78     int u = S;
 79     while(d[S] < N){
 80         if(u == T){
 81             flow += augment();
 82             u = S;
 83         }
 84         int ok = 0;
 85         for(int i = cur[u]; ~i; i = e[i].nex){
 86             int v = e[i].v;
 87             if(d[u] == d[v]+1 && e[i].cap > e[i].flow){
 88                 p[v] = i;
 89                 ok = 1;
 90                 cur[u] = i;
 91                 u = v;
 92                 break;
 93             }
 94         }
 95         if(!ok){
 96             int m = N-1;
 97             for(int i = head[u]; ~i; i = e[i].nex){
 98                 if(e[i].cap > e[i].flow && ~d[e[i].v]) m = min(m, d[e[i].v]);
 99             }
100             if(--num[d[u]] == 0) break;
101             num[d[u]=m+1]++;
102             cur[u] = head[u];
103             if(u != S) u = e[p[u]].u;
104         }
105     }
106     return flow;
107 }
108 int main(){
109     int n, m;
110     init();
111     scanf("%d %d", &n, &m);
112     S = 0;
113     T = n+m+1;
114     N = T+1;
115     int res = 0;
116     int b;
117     for(int i = 1; i <= m; i++){
118         scanf("%d", &b);
119         add(n+i, T, b);
120     }
121     for(int i = 1; i <= n; i++){
122         int a, k, x;
123         scanf("%d %d", &a, &k);
124         add(S, i, a);
125         res += a;
126         for(int j = 0; j < k; j++){
127             scanf("%d", &x);
128             add(i, n+x, inf);
129         }
130     }
131     int ans = ISAP();
132     //cout<<res<<" "<<ans<<endl;
133     printf("%d\n", res - ans);
134 }
View Code

 

以上是关于网络流五·最大权闭合子图 HihoCoder - 1398的主要内容,如果未能解决你的问题,请参考以下文章

[HihoCoder1398]网络流五·最大权闭合子图

hiho一下 第119周 #1398 : 网络流五·最大权闭合子图 最小割-最大流--Ford-Fulkerson 与 Dinic 算法

hihocoder1398 网络流五之最大权闭合子图

最大权闭合子图

网络流——最小割求最大权闭合子图

BZOJ 4873 [Shoi2017]寿司餐厅 | 网络流 最大权闭合子图