【最大流】北大 poj 1274 The Perfect Stall

来源:互联网 发布:java笔试题目 编辑:程序博客网 时间:2024/06/09 18:14


/* THE PROGRAM IS MADE BY PYY *//*----------------------------------------------------------------------------//Copyright (c) 2011 panyanyany All rights reserved.URL   : http://poj.org/problem?id=1274Name  : 1274 The Perfect StallDate  : Sunday, January 1, 2012Time Stage : one hourResult: 9696355panyanyany1274Accepted824K266MSC++1965B2012-01-01 17:35:47Test Data :Review :哦,二分图用网络流来做,就是一个多源多汇点的问题了。不过很显然可以把它转化为单源单汇点问题,那就是以 1~n 为奶牛编号,n+1 ~ n+m 为畜栏编号,添加一个 0 为源点编号,n+m+1 为汇点编号。则此网络流形式为:源点同时与 n 条奶牛相连,奶牛再与畜栏相连,m 个畜栏同时与汇点相连。每条连线的流量设为 1,则源点到汇点的最大流即相当于最大匹配。从而得到解。套模板的题目,很容易过~//----------------------------------------------------------------------------*/#include <stdio.h>#include <string.h>#include <queue>using namespace std ;#define DEBUG#define min(x, y)((x) < (y) ? (x) : (y))#define INF0x3f3f3f3f#define MAXN202*2intn, m ;intmap[MAXN][MAXN], path[MAXN], flow[MAXN] ;int Mark_Points (const int start, const int end){inti, t ;queue<int>q ;memset (path, -1, sizeof (path)) ;flow[start] = INF ;q.push (start) ;while (!q.empty ()){t = q.front () ;q.pop () ;if (end == t)break ;for (i = 0 ; i <= end ; ++i){if (i != start && map[t][i] && path[i] == -1){path[i] = t ;flow[i] = min (flow[t], map[t][i]) ;q.push (i) ;}}}if (path[end] == -1)return -1 ;return flow[end] ;}int Edmonds_Kard (const int start, const int end){intincr, step, curr, prev ;incr = 0 ;while ((step = Mark_Points (start, end)) != -1){incr += step ;curr = end ;while (curr != start){prev = path[curr] ;map[prev][curr] -= step ;map[curr][prev] += step ;curr = prev ;}}return incr ;}int main (void){inti, j ;intnum, stall ;while (~scanf ("%d%d", &n, &m)){memset (map, 0, sizeof (map)) ;for (i = 1 ; i <= n ; ++i){map[0][i] = 1 ;// 源点到各奶牛的流量scanf ("%d", &map[i][0]) ;for (j = 1 ; j <= map[i][0] ; ++j){scanf ("%d", &stall) ;map[i][stall+n] = 1 ;// 奶牛到对应畜栏的流量}}for (i = 1 ; i <= m ; ++i)map[i+n][m+n+1] = 1 ;// 各畜栏到汇点的流量printf ("%d\n", Edmonds_Kard (0, m+n+1)) ;}return 0 ;}


原创粉丝点击