# [UOJ#171]-[wc2016]挑战NPC-带花树+建图

## 题目

UOJ#171传送门
BZOJ4405传送门

### 下面是代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

int T , N , M , E , head[605] , tp ;
int buc[105][3] , ball[305] , id_c , rev[605] ;
struct Path{
int pre , to ;
} p[ 2*(100*300*3*2 + 100*2) + 1000 ] ;

void In( int t1 , int t2 ){
p[++tp] = ( Path ){ head[t1] , t2 } , head[t1] = tp ;
p[++tp] = ( Path ){ head[t2] , t1 } , head[t2] = tp ;
}

int mat[605] , typ[605] , pre[605] ;
int fa[605] , que[605] , fr , ba , ans , tim[605] , tim_c ;
void init(){
id_c = tp = ans = 0 ;
memset( mat , 0 , sizeof( mat ) ) ;
for( int i = 1 ; i <= N ; i ++ ) ball[i] = ++id_c , rev[id_c] = 0 ;
for( int i = 1 ; i <= M ; i ++ ){
for( int j = 0 ; j < 3 ; j ++ )
buc[i][j] = ++id_c , rev[id_c] = i ;
In( buc[i][0] , buc[i][1] ) , In( buc[i][1] , buc[i][2] ) ;
}
}

int find( int x ){
if( fa[x] == x ) return x ;
return fa[x] = find( fa[x] ) ;
}

int getLca( int u , int v ){
tim_c ++ , u = find( u ) , v = find( v ) ;
while( true ){
if( u ){
if( tim[u] == tim_c ) return u ;
tim[u] = tim_c , u = find( pre[ mat[u] ] ) ;
} swap( u , v ) ;
}
}

void blossom( int u , int v , int lca ){
for( ; find( u ) != lca ; ){
pre[u] = v , fa[u] = fa[ mat[u] ] = lca ;
v = mat[u] , u = pre[v] ;
if( typ[v] == 1 ) typ[v] = 0 , que[++ba] = v ;
}
}

bool BFS( int St ){
for( int i = 1 ; i <= id_c ; i ++ )
typ[i] = -1 , fa[i] = i ;
fr = 1 , typ[St] = 0 , que[ ba = 1 ] = St ;
while( ba >= fr ){
int u = que[fr++] ;
for( int i = head[u] ; i ; i = p[i].pre ){
int v = p[i].to ;
if( typ[v] == -1 ){
pre[v] = u , typ[v] = 1 ;
if( !mat[v] ){
for( ; v ; u = pre[v] )
mat[v] = u , swap( mat[u] , v ) ;
return true ;
} else typ[ mat[v] ] = 0 , que[++ba] = mat[v] ;
} else if( !typ[v] && find( u ) != find( v ) ){
int Lca = getLca( u , v ) ;
blossom( u , v , Lca ) ;
blossom( v , u , Lca ) ;
}
}
} return false ;
}

void solve(){
for( int i = 1 ; i <= N ; i ++ )
if( !mat[ ball[i] ] ) ans += BFS( ball[i] ) ;
for( int i = 1 ; i <= M ; i ++ )
for( int j = 0 ; j < 3 ; j ++ )
if( !mat[ buc[i][j] ] ) ans += BFS( buc[i][j] ) ;
printf( "%d\n" , ans - N ) ;
for( int i = 1 ; i <= N ; i ++ )
printf( "%d " , rev[ mat[ball[i]] ] ) ;
puts( "" ) ;
}

int main(){
scanf( "%d" , &T ) ;
while( T -- ){
scanf( "%d%d%d" , &N , &M , &E ) , init() ;
for( int i = 1 , u , v ; i <= E ; i ++ ){
scanf( "%d%d" , &u , &v ) ;
for( int j = 0 ; j < 3 ; j ++ )
In( ball[u] , buc[v][j] ) ;
} solve() ;
}
}


• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120