题目链接:
有两个机器a和b,分别有n个模式和m个模式。下面有k个任务,每个任务需要a的一个模式或者b的一个模式完成。
两个机器初始都是0模式,一个机器转换一个模式需要重启一次。问你最少需要重启几次能完成所有的任务。
不太明显的二分匹配,将每个任务的两个模式连线,大概就能看出来这是个最小点覆盖问题。
1 /* 2 将下面任务的a状态和b状态连边,线的个数就是任务个数。 3 要使重启次数最少,那么就要使选择的点最少而且覆盖所有的边 4 所以问题转化为二分图求最小点覆盖数 5 */ 6 //二分图中 最小点覆盖 = 最大匹配数 7 #include8 #include 9 #include 10 #include 11 using namespace std;12 vector G[105];13 int match[105];14 bool vis[105];15 16 bool dfs(int u) {17 for(int i = 0 ; i < G[u].size() ; ++i) {18 int v = G[u][i];19 if(!vis[v]) {20 vis[v] = true;21 if(match[v] == -1 || dfs(match[v])) {22 match[v] = u;23 return true;24 }25 }26 }27 return false;28 }29 30 int hungry(int n) {31 int res = 0;32 for(int i = 1 ; i <= n - 1 ; ++i) {33 memset(vis , false , sizeof(vis));34 if(dfs(i))35 res++;36 }37 return res;38 }39 40 int main()41 {42 int n , m , k , id , u , v;43 while(~scanf("%d %d %d" , &n , &m , &k) && n) {44 for(int i = 1 ; i <= 100 ; ++i) {45 G[i].clear();46 match[i] = -1;47 vis[i] = false;48 }49 for(int i = 0 ; i < k ; ++i) {50 scanf("%d %d %d" , &id , &u , &v);51 G[u].push_back(v);52 }53 printf("%d\n" , hungry(n));54 }55 return 0;56 }