题意:
有一些两个机器A和B,分别有n种模式和m种模式,
现在有k个任务,每个任务可以在A机器的x模式下完成,也可以在B机器的y模式下完成。
A和B一开始都是模式0,每变换一次模式要重启一次,问最少重启的次数。
思路:
对于每个任务i,设它可以在A的x模式完成也可以在B的y模式完成,则从x到y连一条有向边,问最少需要多少点能覆盖所有的边。
对于二分图,最小点覆盖=最大匹配数,
但是注意,因为两个机器最开始处在模式0,所以当x==0或y==0时不需要连边。
代码(716K,16MS):
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int n, m, k;
vector<int> edges[105];
int mat[105], vis[105];
bool dfs(int k) {
for (int i = 0; i < edges[k].size(); i++) {
int j = edges[k][i];
if (!vis[j]) {
vis[j] = 1;
if (!mat[j] || dfs(mat[j])) {
mat[j] = k;
return true;
}
}
}
return false;
}
int match() {
int ans = 0;
for (int i = 0; i < n; i++) {
memset(vis, 0, sizeof(vis));
if (dfs(i)) ans++;
}
return ans;
}
int main() {
while (~scanf("%d", &n) && n) {
scanf("%d %d", &m, &k);
memset(mat, 0, sizeof(mat));
for (int i = 0; i <= n; i++)
edges[i].clear();
int a, b, c;
for (int i = 0; i < k; i++) {
scanf("%d %d %d", &a, &b, &c);
if (!(b * c)) continue;
edges[b].push_back(c);
}
int ans = match();
printf("%d\n", ans);
}
return 0;
}