1. 程式人生 > >網絡流五·最大權閉合子圖 HihoCoder - 1398

網絡流五·最大權閉合子圖 HihoCoder - 1398

技術 isa tps sap sca ons ble mes blank

網絡流五·最大權閉合子圖

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