HOJ 1056 Machine Schedule (二分图匹配,匈牙利算法)

题意:

给k个任务,每一个任务都能被Computer A的x_mode或Computer B的y_mode处理。mode的转换需要重启。问如何安排任务的处理顺序,可以使得重启的次数最少。

分析:

二分图匹配。将每一个任务看成一条边,端点分别是Computer A的x_mode和Computer B的y_mode。求最小覆盖,即用最少的点数,使得每一条边至少都有一个点与它相连。根据最小覆盖=最大匹配。求该二分图的最大匹配即可。使用匈牙利算法。


代码如下:

#include <iostream>
#include <cstdio>
#include <memory.h>
#define N 105
using namespace std;

int match;
int map[N][N];
int mat[N];
bool used[N];
int n,m,k;
bool crosspath(int k)        //这是一个dfs
{
        for (int i=1;i<=m;i++)           //对于左边每一个点,遍历右边的所有点
        {
                if(map[k][i]==true&&used[i]==false)  //map[i][k]为true且used[i]为false,说明点i在增广路上
                {
                        used[i]=true;
                        if (mat[i]==0 || crosspath(mat[i]))
                        {
                                mat[i]=k;   //将边k-i加入增广路
                                return 1;  //从该点出有可增广路
                        }
                }
        }
        return 0;
}
void hungary()
{
        memset(mat,0,sizeof(mat));
        for (int i=1;i<=n;i++)                      //对二分图的左边进行遍历
        {
                memset(used,0,sizeof(used));
        if(crosspath(i))
            match++;
        }
}

int main()
{

    while(scanf("%d",&n)!=EOF&&n)
    {
        scanf("%d %d",&m,&k);
        int z,x,y;
        memset(map,0,sizeof(map));
        for(int i=1;i<=k;i++)
        {
            scanf("%d %d %d",&z,&x,&y);
            map[x][y]=1;                //邻接矩阵存储图
        }
        match=0;
        hungary();
        printf("%d\n",match);
    }
    return 0;
}


你可能感兴趣的:(HOJ 1056 Machine Schedule (二分图匹配,匈牙利算法))