地址
点击打开链接
这个题目:
有两台机器A和B,A机器有n种工作方式,B机器有m种工作方式。共有k个任务。每个任务恰好在一条机器上运行。
如果任务在A机器上运行,就需要转换为模式Xi,如果在B机器上运行,就需要转换为模式Yi。
每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式需要重启一次。
请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。
需要注意的是,初始状态都在0节点处,所以这种情况不用考虑。也就是为0的时候,直接跳过就好。
剩下的就变成了最小覆盖问题,最小覆盖=n-最大匹配,所以还是hungary算法。
代码::
#include<iostream>
#include<string.h>
#include<cstdio>
#define MAX 105
using namespace std;
int n ,m , k;
int Map[MAX][MAX];//两个人是否有关系
bool used[MAX];//是否被访问过
int linker[MAX];//查看被连接的那一个集合是否有男生来连接了。
bool dfs(int a){
for(int j = 0 ; j < m ; j ++)
{
if(!used[j]&&Map[a][j])
{
used[j]=1 ;
if(linker[j]==-1||dfs(linker[j]))
{
linker[j]=a;
return true ;
}
}
}
return false ;
}
int hungary(){
int ans = 0 ;
memset(linker,-1,sizeof(linker));
for(int i = 0 ; i < n ; i ++)
{
memset(used,0,sizeof(used));
if(dfs(i)) ans+=1;
}
return ans ;
}
int main(){
int i , j ,num,a,b;
while(scanf("%d",&n)&&n)
{
scanf("%d%d",&m,&k);
memset(Map,0,sizeof(Map));
for( i = 0 ; i < k ; i ++)
{
scanf("%d%d%d",&num,&a,&b);
if(a&&b)//这个是因为,一开始状态为0,那么就不再考虑这种情况了,不需要变换
Map[a][b]=1 ;
//Map[b][a]=1 ;//这里不正确,不能加这个,因为加入1 3 有关系,反过来就成 3 1 有关系,因为是两个不同的机器
}
printf("%d\n",hungary());
}
}