这题好早就看过了,没思路,当时。
然后昨天看了黑书上关于最大匹配的知识点,正好有道例题是这个,最小覆盖数,即建成二分图后,求最少的匹配把所有的点都覆盖上。
黑书上有证明,这个最小覆盖数即最大匹配数。(让我想起来最大流就是最小割。。。)
这个题是,给你AB两台机器,每个任务需要A的模式 或者 B的模式,而从A机子切换B需要重启一次,求最少的重启次数。
建图,把AB的模式建成点,边是任务,求最大匹配数即可。
在pojWA掉了,原因是,建图,恩,AB机子的初始模式都是0,所以呢,如果需要0模式的,就不需要要匹配了,直接就可以用这个模式了。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 220 using namespace std; int map[MAX][MAX]; int used[MAX]; int match[MAX]; int n,m; int Augement(int n,int x) { int i; for(i=1; i<=n; i++) if( !used[i] && map[x][i] ) { used[i] = 1; if( match[i] == 0 || Augement(n,match[i]) ) { match[i] = x; return 1; } } return 0; } int Hungary(int n) { int i,sum = 0; memset(match,0,sizeof(match)); for(i=1; i<=n; i++) { memset(used,0,sizeof(used)); if( Augement(n,i) ) sum++; } return sum; } int main() { int i,task,x,y,k,ans; while( ~scanf("%d",&n) && n ) { memset(map,0,sizeof(map)); scanf("%d%d",&m,&k); for(i=1; i<=k; i++) { scanf("%d%d%d",&task,&x,&y); if( x != 0 && y != 0 ) // 因为初始态是0,所以如果需要初始态,就不用建边了。 map[x][n+y] = 1; } ans = Hungary(n+m); printf("%d/n",ans); } return 0; }