Jamie ' s Contact Groups
Time Limit: 7000MS |
|
Memory Limit: 65536K |
Total Submissions: 6902 |
|
Accepted: 2261 |
Description
Jamie is a very popular girl and have quite a lot of friends, so she's always keeps a very long contact list in her cell Phon E. The contact list have become so long that it often takes a long time for she to browse through the whole list to find a Friend ' s number. As Jamie's best friend and a programming genius, you suggest so she group the contact list and minimize the size of the Largest group, so that it would be is easier for she to search for a friend's number among the groups. Jamie takes your advice and gives she entire contact list containing her friends ' names, the number of groups she wish Es to has and what groups every friend could belong to. Your task is to write a program this takes the list and organizes it into groups such that all friend appears in only one Of those groups and the size of the largest group is minimized.
Input
There'll is at the most test cases. Ease case starts with a line containing-integers n and M. where n is the length of the contact list and M are the Numbe R of groups. N lines then follow. Each line contains a friend's name and the groups the friend could belong to. You can assume N are no more than and M are no more than 500. The names would contain alphabet letters only and would be no longer than. No. Friends has the same name. The group label is an integer between 0 and M-1. After the last test case, there was a single line ' 0 0 ' that terminates the input.
Output
For each test case, output a line containing a single integer, the size of the largest contact group.
Sample Input
3 2John 0 1Rose 1Mary 4ACM 1 2 3ICPC 0 1Asian 0 2 3Regional 1 2ShangHai 0 20 0
Sample Output
22
Test instructions: There are n individuals, m groups (0 ~ m-1). Each person can select only one group, and now give the group number that each person has the choice of, the group with the largest number has the sum person, ask the minimum value of sum.
Resolution: The minimum of the maximum is required, and the first response is to find it with two points. Two minutes Juren the largest group of people to have the number of mid.
First constructs the network flow, establishes the super source point, the Super meeting point.
The source points to each person to build the edge, the weight value is 1.
Each person to an optional small build edge, the weight value is 1.
Each group to the meeting point to build the edge, the weight of mid.
Each time you run the network stream, if full stream, the largest number of groups have mid, this situation is possible, if the current large value of the minimum value < Mid, update the minimum value of the maximum value.
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define MAXN 2000# Define MAXM 1000000#define INF 0x3f3f3f3fusing namespace std;int N, m;struct node {int u, V, cap, flow, next;}; Node Edge[maxm];node newedge[maxm];int HEAD[MAXN], Cnt;int NEWHEAD[MAXN], Newcnt;int cur[maxn];int DIST[MAXN], VIS[MAXN ];void init () {cnt = 0; Memset (Head,-1, sizeof (head));} void Add (int u, int v, int w) {node E; EDGE[CNT] = {u, V, W, 0, Head[u]}; Head[u] = cnt++; EDGE[CNT] = {V, u, 0, 0, Head[v]}; HEAD[V] = cnt++;} void Getmap () {char str[100]; for (int i = 1; I <= n; ++i) {Add (0, I, 1);//source point to each person, with a weight of 1 scanf ("%s", str); int A; while (GetChar ()! = ' \ n ') {scanf ("%d", &a); Add (i, a + 1 + N, 1);//Everyone to the corresponding build edge, the weight value is 1}}}bool BFS (int st, int ed) {queue<int>q; memset (Vis, 0, sizeof (VIS)); memset (Dist,-1, sizeof (Dist)); VIS[ST] = 1; DIST[ST] = 0; Q.push (ST); while (!q.empty ()) {int u = q.front (); Q.pop (); for (int i = head[u]; i =-1; i = Edge[i].next) {node E = Edge[i]; if (!VIS[E.V] && e.cap > E.flow) {vis[e.v] = 1; DIST[E.V] = Dist[u] + 1; if (e.v = = ed) return true; Q.push (E.V); }}} return false;} int DFS (int x, int ed, int a) {if (x = = Ed | | a = = 0) return A; int flow = 0, F; for (int &i = cur[x]; I! =-1; i = Edge[i].next) {node &e = Edge[i]; if (dist[e.v] = = Dist[x] + 1 && (f = DFS (e.v, ed, Min (A, e.cap-e.flow))) > 0) {e.flow + = f; edge[i ^ 1].flow-= f; A-= f; Flow + + F; if (a = = 0) break; }} return flow;} int Maxflow (int st, int ed) {int flowsum = 0; while (BFS (st,ed)) {memcpy (cur, head, sizeof (head)); Flowsum + = DFS (St, Ed, INF); } return flowsum;} int main () {while (scanf ("%d%d", &n, &m), n | | m) {init (); Getmap (); memcpy (Newhead, head, sizeof (head)); memcpy (Newedge, Edge, sizeof (edge)); newcnt = CNT; int L = 0, R = N, mid; int ans = n; while (R >= L) {memcpy (head, Newhead, sizeof (Newhead)); memcpy (Edge, Newedge, sizeof (Newedge)); CNT = newcnt; Mid = (L + r)/2; for (int i = 1; I <= m; ++i) {Add (i + N, n + M + 1, mid),//per group to the meeting point} if (Maxflow (0, n + m + 1) = = N) {ans = min (ans, mid); R = mid-1; } else L = mid + 1; } printf ("%d\n", ans); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
POJ 2289--jamie ' s contact Groups "Two-dimensional multi-match problem && binary find maximum minimization && maximum Flow"