题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1191
明显是匹配,可以用网络流来写,对于每一个问题,连边,然后BFS找增广路,如果找不到就直接退出即可。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std ;
#define MAXN 2010
struct edge {
edge *next , *pair ;
int t , f ;
} *head[ MAXN ] ;
void Add( int s , int t , int f ) {
edge *p = new( edge ) ;
p -> t = t , p -> f = f , p -> next = head[ s ] ;
head[ s ] = p ;
}
void AddEdge( int s , int t , int f ) {
Add( s , t , f ) , Add( t , s , 0 ) ;
head[ s ] -> pair = head[ t ] , head[ t ] -> pair = head[ s ] ;
}
int S , T , pre[ MAXN ] , n , m ;
bool f[ MAXN ] ;
edge *aug[ MAXN ] ;
queue < int > Q ;
bool bfs( ) {
memset( f , true , sizeof( f ) ) ; f[ S ] = false ;
while ( ! Q.empty( ) ) Q.pop( ) ;
Q.push( S ) ; pre[ S ] = 0 ;
bool flag = false ;
while ( ! Q.empty( ) ) {
int v = Q.front( ) ; Q.pop( ) ;
for ( edge *p = head[ v ] ; p ; p = p -> next ) if ( p -> f && f[ p -> t ] ) {
f[ p -> t ] = false ; pre[ p -> t ] = v , aug[ p -> t ] = p ;
Q.push( p -> t ) ;
if ( p -> t == T ) {
flag = true ; break ;
}
}
if ( flag ) break ;
}
if ( f[ T ] ) return false ;
for ( int i = T ; pre[ i ] ; i = pre[ i ] ) {
aug[ i ] -> f -- , aug[ i ] -> pair -> f ++ ;
}
return true ;
}
int main( ) {
memset( head , 0 , sizeof( head ) ) ;
scanf( "%d%d" , &n , &m ) ;
T = n + m + 1 , S = n + m + 2 ;
for ( int i = 0 ; i ++ < n ; ) AddEdge( i , T , 1 ) ;
for ( int i = 0 ; i ++ < m ; ) {
int x , y ; scanf( "%d%d" , &x ,&y ) ;
AddEdge( S , n + i , 1 ) , AddEdge( n + i , x + 1 , 1 ) , AddEdge( n + i , y + 1 , 1 ) ;
if ( ! bfs( ) ) {
printf( "%d\n" , i - 1 ) ;
return 0 ;
}
}
printf( "%d\n" , m ) ;
return 0 ;
}