Poj2289: http://poj.org/problem? Id = 2289
A given list of n members should be assigned to M groups, and a possible group number should be given for each person, yes, the largest group is the smallest.
Question: it is obvious that two points. Then, split people and groups.
1 # include <iostream> 2 # include <cstring> 3 # include <algorithm> 4 # include <cstdio> 5 # include <queue> 6 # define INF 100000000 7 using namespace STD; 8 const int n = 3205; 9 const int M = 1000000; 10 struct node {11 int V; 12 int f; 13 int next; 14} edge [m]; 15 int n, m, U, V, CNT, Sx, ex; 16 int head [N], pre [N]; 17 int Val [N] [40]; // apply for 18 void Init () {19 CNT = 0; 20 memset (Head,-1, sizeof (head); 21} 22 void as required Add (int u, int V, int W) {23 edge [CNT]. V = V; 24 edge [CNT]. F = W; 25 edge [CNT]. next = head [u]; 26 head [u] = CNT ++; 27 edge [CNT]. f = 0; 28 edge [CNT]. V = u; 29 edge [CNT]. next = head [v]; 30 head [v] = CNT ++; 31} 32 bool BFS () {33 memset (PRE, 0, sizeof (pre )); 34 pre [SX] = 1; 35 queue <int> q; 36 Q. push (SX); 37 while (! Q. Empty () {38 int d = Q. Front (); 39 Q. Pop (); 40 for (INT I = head [d]; I! =-1; I = edge [I]. Next) {41 if (edge [I]. F &&! Pre [edge [I]. v]) {42 Pre [edge [I]. v] = pre [d] + 1; 43 Q. push (edge [I]. v); 44} 45} 46} 47 return pre [Ex]> 0; 48} 49 int dinic (INT flow, int PS) {50 int F = flow; 51 if (PS = ex) return F; 52 for (INT I = head [PS]; I! =-1; I = edge [I]. next) {53 If (edge [I]. F & Pre [edge [I]. v] = pre [PS] + 1) {54 int A = edge [I]. f; 55 int T = dinic (min (A, flow), edge [I]. v); 56 edge [I]. f-= T; 57 edge [I ^ 1]. F + = T; 58 flow-= T; 59 If (flow <= 0) break; 60} 61 62} 63 If (F-flow <= 0) pre [PS] =-1; 64 return F-flow; 65} 66 int solve () {67 int sum = 0; 68 while (BFS ()) 69 sum + = dinic (INF, SX); 70 return sum; 71} 72 char STR [20]; 73 int ans [N] [N]; 74 int tot [N], top; 75 void build (INT mid) {76 Init (); 77 for (INT I = 1; I <= N; I ++) {78 for (Int J = 1; j <= tot [I]; j ++) {79 add (I + N, ANS [I] [J] + 2 * n, 1 ); 80} 81 add (I, I + N, 1); 82 add (0, I, 1); 83} 84 For (INT I = 1; I <= m; I ++) {85 add (I + 2 * n, I + 2 * n + M, mid); 86 add (I + 2 * n + m, 2 * m + 2 * n + 1, INF); 87} 88} 89 int as, temp; 90 int main () {91 while (~ Scanf ("% d", & N, & M) & N) {92 Init (); 93 as = 0; 94 for (INT I = 1; I <= N; I ++) {95 scanf ("% s", STR); 96 Top = 0; 97 while (getchar ()! = '\ N') {98 scanf ("% d", & temp); 99 // printf ("** % d \ n", temp ); 100 Ans [I] [++ top] = ++ temp; 101} 102 tot [I] = top; 103} 104 int L = 0, r = N; 105 SX = 0, Ex = 2 * n + 2 * m + 1; 106 While (L <= r) {107 int mid = (L + r)/2; 108 build (MID); 109 If (solve () = N) {110 r = mid-1; 111 as = mid; 112} 113 else114 L = Mid + 1; 115} 116 printf ("% d \ n", as); 117 118} 119 return 0; 120}View code
Jamie's contact groups