#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <string.h>
#include <map>
#include <set>
using namespace std;
/*
题意:有2台机器加工零件,第一台有n种工作模式(n0,n1,n2...),第二台有m种工作模式(M0,M1,M2...)初始状态都在0状态,
现在要加工k个零件 输入(i,x,y)意思就是第i个零件可以有第一台机器的x模式做或者第二台机器的y模式做,零件的加工顺序可以任意
但,改变机器的状态需要花费1. 要求加工完零件需要的最小花费.
分析:可以看出这道题是图论,有点像二分图,但是怎么建边?按加工的零件和两台机器建边显然不合理,
分析可以知道,加工一个零件,要么选第一台机器的模式,要么选第二台机器的模式,选了一台就不能选第二台。
可以想到按两台机器建边。加工一个工件用到的种模式就再这两种模式之间建边,这明显是二分图。可以想到最大二分匹配。
但是和这道题有什么关联呢?分析发现,假设选了A机器的一种模式,则在B机器中对应加工这个零件的模式就不能选,意思就是
这两种模式的边被覆盖了,要加工完零件,则需要把所有的边都覆盖完,这不就是最小点覆盖问题吗,它又等于最大二分匹配,
所以要求的就是这个图的最大二分匹配,最后在注意零点模式,因为机器处于零状态,所以,连接两台机器零点的边都可以忽略不计
否则会多算。
*/
int mat[100][100];
int v[110],p[110];
int n,m;
int match(int i)
{
int j;
for(j=1;j<m;j++)
{
if(v[j]==-1&&mat[i][j])
{
v[j]=1;
if(p[j]==-1||match(p[j]))
{
p[j]=i;
return 1;
}
}
}
return 0;
}
int hungry()
{
int re=0;
memset(p,-1,sizeof p);
for(int i=1;i<n;i++)//由于机器初始状态在0,所以去掉0点
{
memset(v,-1,sizeof v);
if(match(i))
{
re++;
}
}
return re;
}
int main()
{
int k,x,y;
int i,id;
while(scanf("%d",&n)!=EOF)
{
if(n==0)break;
scanf("%d%d",&m,&k);
memset(mat,0,sizeof mat);
for(i=1;i<=k;i++)
{
scanf("%d%d%d",&id,&x,&y);
mat[x][y]=1;
}
int ans=hungry();
// if(mat[0][0])
// printf("%d\n",ans-1);
printf("%d\n",ans);
}
return 0;
}
hdu1150 Machine Schedule(最小点覆盖)
最新推荐文章于 2020-07-01 11:34:12 发布