hdu 1150 Machine Schedule

题目大意是有A类机器和B类机器。某个产品生产可以用A类中的某一个或B类中的某一个。如果要使用某个机器(除编号为0的机器外),那么需要一个单位的开机时间,问你最少的开机时间。

对于每一个可以生产同一个产品的机器A和机器B连一条边(每条边代表一个产品)。那么我们要做的就是找到最小的点,使得这些点能覆盖所有的边(这些点能生产所有的的产品)。也就是求二分图的最小点覆盖。

因为用机器0是不需要开机时间的,所以那些可以用机器0完成的产品就不需要再建边了。

#include <iostream>
#include<cstring>
#include<stdio.h>
#define maxn 110
/**
    匈牙利算法 O(VE)
    假设从二分图左边开始找增广路
*/
using namespace std;
int n,m,k;
typedef struct edge
{
    int to,next;
} Edge;
Edge e[1010];
int head[maxn];//邻接表存边,只需维护左边节点的邻接表
int vis[maxn];//右边点访问标记
int mat[maxn];//右边点匹配的左边点
int match;//匹配数

bool crosspath(int k)
{
    for(int i = head[k]; i != -1; i = e[i].next)
    {
        int j = e[i].to;
        if(!vis[j])
        {
            vis[j] = 1;
            if(!mat[j] || crosspath(mat[j]))//右边点未匹配
            {
                mat[j] = k;
                return true;
            }
        }
    }
    return false;
}

void hungary()
{
    for(int i = 0; i <= n; i++)
    {
        memset(vis,0,sizeof vis);
        if(crosspath(i))
        {
            match++;
        }
    }
}

int main()
{
    while(scanf("%d",&n),n)
    {
        scanf("%d %d",&m,&k);
        memset(head,-1,sizeof head);
        memset(mat,0,sizeof mat);
        for(int i = 0; i < k; i++)
        {
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            if(b&&c)//如果能用机器0生产就不用建边
            {
                e[i].to = c;
                e[i].next = head[b];
                head[b] = i;
            }
        }
        match = 0;
        hungary();
        printf("%d\n",match);
    }
    return 0;
}


你可能感兴趣的:(hdu 1150 Machine Schedule)