赞
踩
题目链接:D. Captain America
上下界最小流模板题,离散化建图跑即可。
By No.baka, contest: Codeforces Round #366 (Div. 1), problem: (D) Captain America, Accepted, #
#include <bits/stdc++.h>
using namespace std ;
#define clr( a , x ) memset ( a , x , sizeof a )
#define cpy( a , x ) memcpy ( a , x , sizeof a )
const int MAXN = 200005 ;
const int MAXE = 1000000 ;
const int INF = 0x3f3f3f3f ;
struct Edge {
int v , c , n ;
Edge () {}
Edge ( int v , int c , int n ) : v ( v ) , c ( c ) , n ( n ) {}
} ;
namespace Flow {
Edge E[MAXE] ;
int H[MAXN] , cntE ;
int d[MAXN] , cur[MAXN] , pre[MAXN] , gap[MAXN] ;
int Q[MAXN] , head , tail ;
int flow ;
void init () {
cntE = 0 ;
clr ( H , -1 ) ;
}
void addedge ( int u , int v , int c ) {
E[cntE] = Edge ( v , c , H[u] ) ;
H[u] = cntE ++ ;
E[cntE] = Edge ( u , 0 , H[v] ) ;
H[v] = cntE ++ ;
}
void rev_bfs ( int s , int t , int nv ) {
head = tail = 0 ;
clr ( d , -1 ) ;
clr ( gap , 0 ) ;
d[t] = 0 ;
gap[0] = 1 ;
Q[tail ++] = t ;
while ( head != tail ) {
int u = Q[head ++] ;
for ( int i = H[u] ; ~i ; i = E[i].n ) {
int v = E[i].v ;
if ( d[v] == -1 ) {
d[v] = d[u] + 1 ;
Q[tail ++] = v ;
gap[d[v]] ++ ;
}
}
}
}
int isap ( int s , int t , int nv ) {
cpy ( cur , H ) ;
rev_bfs ( s , t , nv ) ;
flow = 0 ;
int u = pre[s] = s , i ;
while ( d[s] < nv ) {
if ( u == t ) {
int f = INF ;
for ( i = s ; i != t ; i = E[cur[i]].v ) {
if ( f > E[cur[i]].c ) {
f = E[cur[i]].c ;
u = i ;
}
}
for ( i = s ; i != t ; i = E[cur[i]].v ) {
E[cur[i]].c -= f ;
E[cur[i] ^ 1].c += f ;
}
flow += f ;
}
for ( i = cur[u] ; ~i ; i = E[i].n ) {
if ( E[i].c && d[u] == d[E[i].v] + 1 ) break ;
}
if ( ~i ) {
cur[u] = i ;
pre[E[i].v] = u ;
u = E[i].v ;
} else {
if ( 0 == -- gap[d[u]] ) break ;
int minv = nv ;
for ( i = H[u] ; ~i ; i = E[i].n ) {
int v = E[i].v ;
if ( E[i].c && minv > d[v] ) {
minv = d[v] ;
cur[u] = i ;
}
}
d[u] = minv + 1 ;
gap[d[u]] ++ ;
u = pre[u] ;
}
}
return flow ;
}
} ;
using namespace Flow ;
int n , m ;
int in[MAXN] ;
int su[MAXN] , vt[MAXN] ;
int numr[MAXN] , numc[MAXN] ;
int eu[MAXN] , ev[MAXN] ;
map < int , int > mpr , mpc ;
int Rcnt , Ccnt ;
int s , t , nv ;
int ss , tt ;
int ans[MAXN] ;
int getr ( int x ) {
if ( mpr.count ( x ) ) return mpr[x] ;
return mpr[x] = ++ Rcnt ;
}
int getc ( int x ) {
if ( mpc.count ( x ) ) return mpc[x] ;
return mpc[x] = ++ Ccnt ;
}
void solve () {
int flag = 0 , red , blue ;
Rcnt = Ccnt = 0 ;
mpr.clear () ;
mpc.clear () ;
clr ( in , 0 ) ;
clr ( su , 0 ) ;
clr ( vt , 0 ) ;
clr ( ans , 0 ) ;
clr ( numr , 0 ) ;
clr ( numc , 0 ) ;
init () ;
scanf ( "%d%d" , &red , &blue ) ;
if ( red > blue ) {
swap ( red , blue ) ;
flag = 1 ;
}
blue -= red ;
for ( int i = 0 ; i < n ; ++ i ) {
int u , v ;
scanf ( "%d%d" , &u , &v ) ;
u = getr ( u ) ;
v = getc ( v ) ;
eu[i] = u ;
ev[i] = v ;
numr[u] ++ ;
numc[v] ++ ;
}
for ( int i = 1 ; i <= n ; ++ i ) {
addedge ( eu[i - 1] , ev[i - 1] + Rcnt , 1 ) ;
su[i] = numr[i] ;
vt[i] = numc[i] ;
}
int ok = 1 ;
for ( int i = 0 ; i < m ; ++ i ) {
int x , v , op ;
scanf ( "%d%d%d" , &op , &x , &v ) ;
if ( op == 1 ) {
if ( !mpr.count ( x ) ) continue ;
x = mpr[x] ;
int L = ( numr[x] - v + 1 ) / 2 ;
int R = numr[x] - L ;
if ( L > R ) ok = 0 ;
su[x] = min ( su[x] , R ) ;
in[x] = max ( in[x] , L ) ;
} else {
if ( !mpc.count ( x ) ) continue ;
x = mpc[x] ;
int L = ( numc[x] - v + 1 ) / 2 ;
int R = numc[x] - L ;
if ( L > R ) ok = 0 ;
vt[x] = min ( vt[x] , R ) ;
in[x + Rcnt] = max ( in[x + Rcnt] , L ) ;
}
}
if ( !ok ) {
printf ( "-1\n" ) ;
return ;
}
s = 0 ;
t = Rcnt + Ccnt + 1 ;
ss = t + 1 ;
tt = ss + 1 ;
nv = tt + 1 ;
int tot = 0 ;
for ( int i = 1 ; i <= Rcnt ; ++ i ) {
//printf ( "R %d: %d\n" , i , su[i] ) ;
in[s] += in[i] ;
if ( su[i] - in[i] ) addedge ( s , i , su[i] - in[i] ) ;
if ( in[i] ) addedge ( ss , i , in[i] ) ;
tot += in[i] ;
}
for ( int i = 1 ; i <= Ccnt ; ++ i ) {
//printf ( "C %d: %d\n" , i , vt[i] ) ;
in[t] += in[i + Rcnt] ;
if ( vt[i] - in[i + Rcnt] ) addedge ( i + Rcnt , t , vt[i] - in[i + Rcnt] ) ;
if ( in[i + Rcnt] ) addedge ( i + Rcnt , tt , in[i + Rcnt] ) ;
tot += in[i + Rcnt] ;
}
addedge ( s , tt , in[s] ) ;
addedge ( ss , t , in[t] ) ;
int f = isap ( ss , tt , nv ) ;
addedge ( t , s , INF ) ;
f += isap ( ss , tt , nv ) ;
if ( f != tot ) {
printf ( "-1\n" ) ;
return ;
}
for ( int i = 1 ; i <= Rcnt ; ++ i ) {
for ( int j = H[i] ; ~j ; j = E[j].n ) {
int v = E[j].v ;
if ( v > Rcnt && v <= Rcnt + Ccnt && E[j ^ 1].c ) {
ans[j >> 1] = 1 ;
}
}
}
printf ( "%I64d\n" , 1LL * E[H[t] ^ 1].c * blue + 1LL * n * red ) ;
for ( int i = 0 ; i < n ; ++ i ) {
printf ( "%c" , ( flag ^ ans[i] ) ? 'b' : 'r' ) ;
}
puts ( "" ) ;
}
int main () {
while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
return 0 ;
}
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。