[최대 흐름+dinic+2 분 매 거 진]북 대 poj 3189 Steady Cow 할당

5371 단어 dinic
/* THE PROGRAM IS MADE BY PYY */
/*----------------------------------------------------------------------------//
    Copyright (c) 2012 panyanyany All rights reserved.

    URL   : http://poj.org/problem?id=3189
    Name  : 3189 Steady Cow Assignment

    Date  : Monday, February 13, 2012
    Time Stage : 5 hours

    Result:
9802586	panyanyany
3189
Accepted	948K	329MS	C++
4870B	2012-02-13 21:00:17

Test Data :

Review :
       ,wa   ,    ,  WA……
          3     ……   ……
         ,      ,          ,     ……

           ,     ,      ,        。
    ,     ,           ,              
       。

         ,     x       ,         ,   2   ,
    ,   [1,2],[2,3],[3,4]。    ,2      ,     ,       
       1    2    ,              2    3    ……

//----------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


#define MEM(a, v)		memset (a, v, sizeof (a))	// a for address, v for value
#define max(x, y)		((x) > (y) ? (x) : (y))
#define min(x, y)		((x) < (y) ? (x) : (y))

#define INF		(0x3f3f3f3f)
#define MAXN	(1002*2)
#define MAXE	(MAXN*22*4)

#define DB	/##/

struct EDGE {
	int u, v, c, n ;
};

int		n, b, eCnt, s, t ;
int		dist[MAXN], q[MAXN], vertex[MAXN], barn[MAXN][22], cap[22] ;
EDGE	edge[MAXE] ;

inline void init()
{
	eCnt = 0 ;
	MEM (vertex, -1) ;
}

inline void insert (const int u, const int v, const int c)
{
	edge[eCnt].u = u ;
	edge[eCnt].v = v ;
	edge[eCnt].c = c ;
	edge[eCnt].n = vertex[u] ;
	vertex[u] = eCnt++ ;

	edge[eCnt].u = v ;
	edge[eCnt].v = u ;
	edge[eCnt].c = 0 ;
	edge[eCnt].n = vertex[v] ;
	vertex[v] = eCnt++ ;
}

int dinic (int beg, int end)
{
	int ans = 0 ;
	while (true)
	{
		int head, tail, u, v, e ;

		MEM(dist, -1) ;
		head = tail = 0 ;
		q[tail++] = beg ;
		dist[beg] = 0 ;

		//   ,     
		while (head < tail)
		{
			v = q[head++] ;
			for (e = vertex[v] ; e != -1 ; e = edge[e].n)
			{
				u = edge[e].u ;
				int to = edge[e].v ;
				int cost = edge[e].c ;
				if (cost > 0 && dist[to] == -1)
				{
					dist[to] = dist[u] + 1 ;
					q[tail++] = to ;
					if (to == end)
					{
						head = tail ;
						break ;
					}
				}
			}
		}
		if (dist[end] == -1)
			break ;
		// v            
		v = beg ;
		tail = 0 ;
		while (true)
		{
DB			printf("--- tail:%d ", tail) ;
			if (v == end)
			{
				int i, flow = INF, ebreak ;
				//              
				for (i = 0 ; i < tail ; ++i)
					if (flow > edge[q[i]].c)
					{
						flow = edge[q[i]].c ;
						ebreak = i ;
					}
				ans += flow ;
				//           ,          
				for (i = 0 ; i < tail ; ++i)
				{
					edge[q[i]].c -= flow ;		//      
					edge[q[i]^1].c += flow ;	//      
				}
				//            0           
				v = edge[q[ebreak]].u ;
				tail = ebreak ;
DB				printf ("end --- v:%d ebreak:%d, ans:%d
", v, ebreak, ans) ; } // // , v , // find a way from e to any vertex in "layers" for (e = vertex[v] ; e != -1 ; e = edge[e].n) { // -1 + 1 == 0 , dist[edge[e].u] > -1 // , , // , dist[u] -1 if (edge[e].c > 0 && //dist[edge[e].u] > -1 && dist[edge[e].u]+1 == dist[edge[e].v]) { // printf ("dist[%d]+1 == dist[%d]: %d+1 == %d
", // edge[e].u, edge[e].v, dist[edge[e].u], dist[edge[e].v]) ; break ; } } DB printf ("v:%d, e:%d, edge[%d]: u:%d, v:%d, c:%d, n:%d
", \ v, e, e, edge[e].u, edge[e].v, edge[e].c, edge[e].n) ; // system ("pause 1>>nul 2>>nul") ; // vertex[v] if (e == -1) // no way from current edge's next vertex { // if (tail == 0) // no edges in queue break ; // vertex[v] // // dist[edge[q[--tail]].u] = -1 // …… , …… dist[edge[q[--tail]].v] = -1 ; // , vertex[v] v = edge[q[tail]].u ; // backward to previous vertex DB printf ("e == -1 ----- v:%d, tail:%d
", v, tail) ; } else // put the edge in queue { // , q[tail++] = e ; // v = edge[e].v ; } DB puts ("") ; } } return ans ; } int makegraph (const int lim) { int i, j, low ; for (low = 1 ; low <= b - (lim - 1) ; ++low) { init(); for (i = 1 ; i <= n ; ++i) { insert (s, i, 1) ; for (j = low ; j <= low + (lim-1) ; ++j) insert (i, barn[i][j]+n, 1) ; } for (i = 1 ; i <= b ; ++i) insert (i+n, t, cap[i]) ; if (dinic(s, t) == n) return true ; } return false ; } int main() { int i, j ; int ans, low, hig, mid ; while (scanf("%d%d", &n, &b) != EOF) { for (i = 1 ; i <= n ; ++i) { for (j = 1 ; j <= b ; ++j) { scanf ("%d", &barn[i][j]) ; } } for (i = 1 ; i <= b ; ++i) scanf ("%d", &cap[i]) ; s = 0 ; t = n+b+1 ; low = 1 ; hig = b ; ans = -1 ; while (low <= hig) { mid = (low + hig) / 2 ; if (makegraph (mid)) { ans = mid ; hig = mid - 1 ; } else low = mid + 1 ; } printf ("%d
", ans) ; } return 0 ; }

좋은 웹페이지 즐겨찾기