题意:两台机器 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 两种机器联想到二部图,将问题转化为最小点覆盖集问题,而最小点覆盖集 = 最大匹配数。然后你懂的。
操作数 = 最大匹配数,用匈牙利算法求解吧。

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 }