题目链接:
题意:
有两台机器A和B,A机器有n种工作方式,B机器有m种工作方式。共有k个任务。每个任务恰好在一条机器上运行。
如果任务在A机器上运行,就需要转换为模式Xi,如果在B机器上运行,就需要转换为模式Yi。
每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。
请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。
思路:
把机器A的N种模式作为二分图的左部,机器B的M种模式作为二分图的右部,如果某个任务可以使用机器A的模式xi也可以使用机器B的模式yi完成,则连接xi,yi。
题目要求使机器重启的次数要尽量少,又要把所有的任务都执行完,也就可以把题目转换成最小顶点覆盖,根据二分图的性质:最小顶点覆盖=最大匹配数。
AC代码如下:
#include<stdio.h>
#include<string.h>
#define N 202
int vis[N]; //记录y中节点是否使用 0表示没有访问过,1为访问过
int link[N]; //记录当前与y节点相连的x的节点
int map[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
int gn,gm; //二分图中x和y中点的数目
int can(int t)
{
int i;
for(i=0;i<gm;i++)
{
if(vis[i]==0&&map[t][i])
{
vis[i]=1;
if(link[i]==-1||can(link[i]))
{
link[i]=t;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int i,num;
num=0;
memset(link,0xff,sizeof(link));
for(i=0;i<gn;i++)
{
memset(vis,0,sizeof(vis));
if(can(i)) num++;
}
return num;
}
int main()
{
int k;
while(scanf("%d",&gn),gn!=0)
{
scanf("%d%d",&gm,&k);
memset(map,0,sizeof(map));
while(k--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>0&&c>0)
{
map[b][c]=1;
}
}
printf("%d\n",MaxMatch());
}
}