以任务作为边,机器的模式为点。如果一任务可以由A机器的模式i或B机器的模式j加工,那么ij连边,边代表该任务。于是问题变成了求以最少的点来覆盖所有边的问题,即最小点覆盖,即可在转变成由求最大匹配得到。运用著名的匈牙利算法即可快速的求解该问题。需要注意的是由于机器开始都处于0模式,所以如果有任务可以有任一种机器的0模式加工的话可先直接加工该任务而不要重启机器,即不要连边。
#include<iostream>
using namespace std;
int n,m,k;
int Map[110][110];
int match;
int use[110];
int mat[110];
bool crosspath(int k)
{ int i,j;
for(i=1;i<=Map[k][0];i++)
{
j=Map[k][i];
if(!use[j])
{
use[j]=1;
if(mat[j]==-1||crosspath(mat[j]))
{
mat[j]=k;
return true;
}
}
}
return false;
}
void hungary()
{ int i;
for(i=0;i<n;i++)
{
if(crosspath(i))
match++;
memset(use,0,sizeof(use));
}
}
int main()
{
int i,j,x,y;
while(scanf("%d",&n)&&n)
{
scanf("%d%d",&m,&k);
memset(mat,-1,sizeof(mat));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
Map[i][j]=0;
}
for(j=1;j<=k;j++)
{
scanf("%d%d%d",&i,&x,&y);
if(x*y==0)
continue;
Map[x][++Map[x][0]]=y;
}
hungary();
printf("%d\n",match);
match=0;
}
return 0;}