[최대 흐름+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 ;
}