poj 1149
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #define _clr(x, y) memset(x, y, sizeof(x)) 5 #define Min(x, y) (x < y ? x : y) 6 #define INF 0x3f3f3f3f 7 #define N 150 8 #define M 1005 9 using namespace std; 10 11 int resi[N][N], h[N], ef[N]; 12 int dist[N], pre[N]; 13 int Maxf, S, T; 14 bool used[N]; 15 queue<int> Q; 16 17 // 一般预流推进算法 --47ms 18 void Push(int x) 19 { 20 for(int i=0; i<=T; i++) 21 { 22 int tmp = Min(ef[x], resi[x][i]); 23 if(tmp>0 && (x==S || h[x]==h[i]+1)) 24 { 25 resi[x][i] -= tmp, resi[i][x] += tmp; 26 ef[x] -= tmp, ef[i] += tmp; 27 if(i==T) Maxf += tmp; 28 if(i!=S && i!=T) Q.push(i); 29 } 30 } 31 } 32 33 void Push_Relabel(int n) 34 { 35 Maxf = 0; 36 _clr(ef, 0); 37 _clr(h, 0); 38 h[S] = n, ef[S]=INF, ef[T]=-INF; 39 Q.push(S); 40 while(!Q.empty()) 41 { 42 int x = Q.front(); 43 Q.pop(); 44 Push(x); 45 if(x!=S && x!=T && ef[x]>0) 46 { 47 h[x]++; 48 Q.push(x); 49 } 50 } 51 printf("%d\n",Maxf); 52 } 53 54 void Init(int m, int n) 55 { 56 int pig[M], last[M]; 57 int num, k; 58 S=0, T=n+1; 59 _clr(last, 0); 60 _clr(resi, 0); 61 for(int i=1; i<=m; i++) 62 scanf("%d", pig+i); 63 for(int i=1; i<=n; i++) 64 { 65 scanf("%d", &num); 66 for(int j=0; j<num; j++) 67 { 68 scanf("%d", &k); 69 if(last[k]==0) 70 resi[S][i] += pig[k]; 71 else 72 resi[last[k]][i] = INF; 73 last[k] = i; 74 } 75 scanf("%d", resi[i]+T); 76 } 77 } 78 79 // 连续最短曾广路算法 --17ms 80 bool bfs_dinic() 81 { 82 _clr(dist, -1); 83 dist[S] = 0; 84 Q.push(S); 85 while(!Q.empty()) 86 { 87 int u = Q.front(); 88 Q.pop(); 89 for(int i=0; i<=T; i++) 90 { 91 if(dist[i]<0 && resi[u][i]) 92 { 93 dist[i] = dist[u]+1; 94 Q.push(i); 95 } 96 } 97 } 98 return dist[T]>0 ? 1 : 0; 99 } 100 101 int dfs(int x, int f) 102 { 103 int a=0; 104 if(x==T) return f; 105 for(int i=0; i<=T; i++) 106 { 107 if(resi[x][i] && dist[i]==dist[x]+1 && (a=dfs(i, Min(f, resi[x][i])))) 108 { 109 resi[x][i] -= a, resi[i][x] += a; 110 return a; 111 } 112 } 113 return 0; 114 } 115 116 void Dinic() 117 { 118 int ans=0, a; 119 while(bfs_dinic()) 120 while(a=dfs(0, INF)) ans+= a; 121 printf("%d\n", ans); 122 } 123 124 // EK算法 --0ms 125 bool bfs() 126 { 127 _clr(used, 0); 128 _clr(pre, -1); 129 int Sta[N], top=0; 130 used[S] = true; 131 Sta[top++] = S; 132 while(top) 133 { 134 int u = Sta[--top]; 135 for(int i=0; i<=T; i++) 136 { 137 if(resi[u][i] && !used[i]) 138 { 139 used[i] = true; 140 pre[i] = u; 141 if(i==T) return true; 142 Sta[top++] = i; 143 } 144 } 145 } 146 return false; 147 } 148 void EK() 149 { 150 int maxf=0, d; 151 while(bfs()) 152 { 153 d = INF; 154 for(int i=T; i!=S; i=pre[i]) 155 d = Min(d, resi[pre[i]][i]); 156 for(int i=T; i!=S; i=pre[i]) 157 { 158 resi[pre[i]][i] -= d; 159 resi[i][pre[i]] += d; 160 } 161 maxf += d; 162 } 163 printf("%d\n", maxf); 164 } 165 int main() 166 { 167 int n, m; 168 while(~scanf("%d%d", &m, &n)) 169 { 170 while(!Q.empty()) Q.pop(); 171 Init(m, n); 172 EK(); 173 //Push_Relabel(n); 174 //Dinic(); 175 } 176 return 0; 177 }