Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 2847 | Accepted: 912 |
Description
Input
Output
Sample Input
3 2 John 0 1 Rose 1 Mary 1 5 4 ACM 1 2 3 ICPC 0 1 Asian 0 2 3 Regional 1 2 ShangHai 0 2 0 0
Sample Output
2 2
#include <stdio.h> #include <string.h> const int inf=1<<30; #define MAXM 2000 struct edge { int from, to, val, next; }e[MAXM*MAXM]; int map[MAXM][MAXM],v[MAXM],in[MAXM]; int n,m,len,st,ed,v_count; //st = 源点 ed = 汇点 v_count = 总的节点数 void init() { char str[20]; char ch; int x; memset(map,0,sizeof(map)); memset(in,0,sizeof(in)); st = 0; ed = n + m + 1; for (int i = 1;i <= n;i ++) { scanf("%s",str); while (1) { ch = getchar(); if(ch == '/n') break; scanf("%d",&x); map[i][x+1] = 1; in[x+1]++; } } v_count = n + m + 2; } void insert(int from, int to, int va) { e[len].from = from, e[len].to = to; e[len].val = va; e[len].next = v[from]; v[from] = len++; e[len].from = to, e[len].to = from; e[len].val = 0; e[len].next = v[to]; v[to] = len++; } void build(int limit) { int i,j; memset(v,-1,sizeof(v)); len = 0; for (i = 1;i <= n;i ++) { insert(0,i,1); for (j = 1;j <= m;j ++) { if(map[i][j]) insert(i,j+n,1); } } for (i = 1;i <= m;i ++) { if(in[i] >= limit) insert(i+n,ed,limit); else insert(i+n,ed,in[i]); } } int sap() { int dist[MAXM],now[MAXM],cnt[MAXM],pre[MAXM],cur[MAXM]; int tot_flow; int now_flow, found, min; int i, j, t; memset(dist, 0, sizeof(dist)); memset(now, -1, sizeof(now)); memset(cnt, 0, sizeof(cnt)); i = st; tot_flow = 0; now_flow = inf; cnt[0] = v_count; while(dist[st] < v_count) { cur[i] = now_flow; found = 0; if(now[i] == -1) t = v[i]; else t = now[i]; while(t != -1) { j = e[t].to; if(e[t].val > 0 && dist[j] + 1 == dist[i]) { found = 1; now[i] = t; if(e[t].val < now_flow) now_flow = e[t].val; pre[j] = t; i = j; if(i == n+m+1) { tot_flow += now_flow; while(i != st) { e[pre[i]].val -= now_flow; e[pre[i]^1].val += now_flow; i = e[pre[i]].from; } now_flow = inf; } break; } t = e[t].next; } if(found) continue; if(--cnt[dist[i]] == 0) break; min = v_count - 1; t = v[i]; while(t != -1) { if(e[t].val > 0 && dist[e[t].to] < min) { min = dist[e[t].to]; now[i] = t; } t = e[t].next; } dist[i] = min + 1; cnt[dist[i]]++; if(i != st) { i = e[pre[i]].from; now_flow = cur[i]; } } return tot_flow; } void slove() { int low,high,mid; low = 0;high = n; int res; while (low < high) { mid = (low + high) >> 1; build(mid); res = sap(); if(res >= n) high = mid; else low = mid + 1; } printf("%d/n",low); } int main() { while (scanf("%d%d",&n,&m),n+m) { getchar(); init(); slove(); } return 0; }