题意: 有两台机器A,B,A机器有n种模式,B机器有m种模式,有k个作业,每个作业可以通过A的某个模式来做也可以通过B的某个模式来做,AB两台机器切换模式需要重启,求最小的重启次数。
解法:A,B其实是二分图的两个点集合,可以写同一个作业的两个模式连一条边,这里是求最小点覆盖,最小点覆盖等于最大匹配,跑一遍最大匹配就是答案了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
bool g[110][310];
bool flag,visit[310];
int match[310];
int p,n;
bool dfs(int u)
{
for (int i = 1; i < n; ++i)
{
if (g[u][i] && !visit[i])
{
visit[i] = true;
if (match[i] == -1 || dfs(match[i]))
{
match[i] = u;
return true;
}
}
}
return false;
}
int main()
{
int k;
while(~scanf("%d",&p))
{
if(p == 0) return 0;
scanf("%d%d",&n,&k);
memset(g,false,sizeof(g));
memset(match,-1,sizeof(match));
for(int i = 0; i < k; i++)
{
int x,u,v;
scanf("%d%d%d",&x,&u,&v);
g[u][v] = true;
}
int ans = 0;
for(int i = 1; i < p; i++)
{
memset(visit,false,sizeof(visit));
if(dfs(i))
ans ++;
}
printf("%d\n",ans);
}
return 0;
}