blue sea  
As an ACMer, not only try, but also create.

题意:两台机器 A, B。初始状态为 mode_0 工作模式,有k件工作时,就有 0~k-1 个工作模式。其中第 i 项工作可由 A 机器的 mode_x 或者 B 机器的 mode_y 来完成。不过机器转换模式需要手动操作。
给出 k 项工作的要求,请求出完成 k 项工作最小需要的操作时。
思路:第 i 项工作可由 A 机器的 mode_x 或者 B 机器的 mode_y 来完成,最小的操作数,一定是使用最少数量的机器模式,这些模式能完成所有的工作。
以此为构图思路,将工作做边,模式做点,A, B 两种机器联想到二部图,将问题转化为最小点覆盖集问题,而最小点覆盖集 = 最大匹配数。然后你懂的。
操作数 = 最大匹配数,用匈牙利算法求解吧。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define MAXN 110
 6 int nx, ny, task;
 7 int xs[MAXN*MAXN], ys[MAXN*MAXN];
 8 bool g[MAXN][MAXN], mark[MAXN*MAXN];
 9 int dfs( int u )
10 {
11     int v;
12     for( v = 1; v < ny; v++ )
13     {
14         if( g[u][v] && !mark[v] )
15         {
16             mark[v] = true;
17             if( !ys[v] || dfs( ys[v] ) )
18             {
19                 xs[u] = v;
20                 ys[v] = u;
21                 return 1;
22             }
23         }
24     }
25     return 0;
26 }
27 int MaxMatch()
28 {
29     int u, tot;
30     tot = 0;
31     memset( xs, 0, sizeof(xs) );
32     memset( ys, 0, sizeof(ys) );
33     for( u = 1; u < nx; u++ )
34     {
35         if( !xs[u] )
36         {
37             memset( mark, false, sizeof(mark) );
38             tot += dfs( u );
39         }
40     }
41     return tot;
42 }
43 int main()
44 {
45     int num, u, v;
46     while( ~scanf( "%d", &nx ), nx )
47     {
48         memset( g, false, sizeof(g) );
49         scanf( "%d%d", &ny, &task );
50         while( task-- )
51         {
52             scanf( "%d%d%d", &num, &u, &v );
53             g[u][v] = true;
54         }
55         printf( "%d\n", MaxMatch() );
56     }
57     return 0;
58 }

 

posted on 2013-01-23 19:43  wide sea  阅读(150)  评论(0)    收藏  举报