POJ 1235 Machine Schedule 【二分图】

这道题考察对最小点覆盖的理解。

做法:

对于一个作业,它需要A的a模式和B的b模式,那么可以从a模式向b模式连一条边;可以感性的理解为每一条边就是一个作业,需要求得有多少个模式可以覆盖所有的边,也就是最小点覆盖,也就是最大匹配。

注意 :

由于A,B的机器初始模式为0,那么所有的可以用模式0完成的工作都可以不用更换模式而完成!所以我们只需要考虑完成模式不包含0的作业。

AC代码:

 1 #include <vector>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 const  int  N = 5000 + 5 ;
 6 
 7 std :: vector < int >  g [ N ] ;
 8 int  link [ N ] , n , k , m , ans , x , a , b ;
 9 bool  vis [ N ] ;
10 
11 void  create ( int  u , int  v ) {
12     g [ u ] . push_back ( v ) ;
13 }
14 
15 bool  find ( int  x ) {
16     int  v ; 
17     for ( int  i = 0; i < g [ x ] . size ( ) ; i ++ ) {
18         v = g [ x ] [ i ] ;
19         if ( ! vis [ v ] ) {
20             vis [ v ] = true ;
21             if ( ( ! link [ v ] )  ||  find ( link [ v ] ) ) {
22                 link [ v ] = x ;
23                 return  true ;
24             }
25         }
26     }
27     return  false ;
28 }
29 
30 void  init ( ) {
31     memset ( link , 0 , sizeof ( link ) ) ;
32     ans = 0 ;
33 }
34 
35 int  main ( ) { // 待调试 
36     while ( 1 ) {
37         scanf ( "%d" , & n ) ;
38         if ( n == 0 )  return  0 ;
39         scanf ( "%d%d" , & m , & k ) ;
40         init ( ) ;
41         // A : 1 ~ n ;
42         // B : n + 1 ~ n + m ;
43         for ( int  i = 1 ; i <= k ; i ++ ) {
44             scanf ( "%d%d%d" , & x , & a , & b ) ;
45             if ( a * b != 0 )  create ( a , b + n ) ;
46         }
47         for ( int  i = 1 ; i <= n ; i ++ ) {
48             memset ( vis , false , sizeof ( vis ) ) ;
49             if ( find ( i ) ) 
50                 ans ++ ;
51         }
52         printf ( "%d\n" , ans ) ;
53         for ( int  i = 1 ; i <= n + m ; i ++ ) 
54             g [ i ] . clear ( ) ;
55     }
56 } 
AC

猜你喜欢

转载自www.cnblogs.com/horsepower2001/p/8975792.html