Question: Divide n friends into m groups. Find the minimum number of people in each group ,,,
The maximum stream + two points, and isap run quite fast ,,,
# Include <stdio. h> # include <string. h> const int n= 1510; const int inf = 0x3fffffff; int dis [N], gap [N], head [N], num, start, ans, end, first [N], nume, n, m; struct edge {int st, ed, flow, next;} E [510000]; struct node {int x, next ;} e [510000]; void addedge (int x, int y, int w) {E [num]. st = x; E [num]. ed = y; E [num]. flow = w; E [num]. next = head [x]; head [x] = num ++; E [num]. st = y; E [num]. ed = x; E [num]. flow = 0; E [num]. next = head [y]; head [y] = num ++;} void Add Edge (int x, int y) {e [nume]. x = y; e [nume]. next = first [x]; first [x] = nume ++;} int dfs (int u, int minflow) {if (u = end) return minflow; int I, v, f, flow = 0, min_dis = ans-1; for (I = head [u]; I! =-1; I = E [I]. next) {if (E [I]. flow> 0) {v = E [I]. ed; if (dis [v] + 1 = dis [u]) {f = dfs (v, E [I]. flow> minflow-flow? Minflow-flow: E [I]. flow); E [I]. flow-= f; E [I ^ 1]. flow + = f; if (flow = minflow) break; if (dis [start]> = ans) return flow ;} min_dis = min_dis> dis [v]? Dis [v]: min_dis; }}if (flow = 0) {if (-- gap [dis [u] = 0) dis [start] = ans; dis [u] = min_dis + 1; gap [dis [u] ++;} return flow;} int isap () {int maxflow = 0; memset (dis, 0, sizeof (dis); memset (gap, 0, sizeof (gap); gap [0] = ans; while (dis [start] <ans) maxflow + = dfs (start, inf); return maxflow;} void makemap (int D) {memset (head,-1, sizeof (head); num = 0; int I, j; for (I = 1; I <= n; I ++) {addedge (start, I, 1); for (j = first [I]; j! =-1; j = e [j]. next) addedge (I, n + e [j]. x, 1) ;}for (I = 1; I <= m; I ++) addedge (I + n, end, D) ;} int main () {int I, j, k, flag, left, right, mid; char str [3000]; while (scanf ("% d", & n, & m ), n | m) {getchar (); memset (first,-1, sizeof (first); nume = 0; start = 0; end = n + m + 1; ans = end + 1; for (I = 1; I <= n; I ++) {gets (str); k = 0; flag = 0; for (j = 0; str [j]; j ++) {if (str [j]> = '0' & str [j] <= '9 ') {k = k * 10 + str [j]-'0'; flag = 1;} else if (flag = 1) {Addedge (I, k + 1 ); flag = 0; k = 0; }}if (flag = 1) Addedge (I, k + 1);} left = 0; right = n; while (left <right) {mid = (left + right)/2; // makemap (mid); if (isap () = n) right = mid; else left = mid + 1;} printf ("% d \ n", right);} return 0 ;}