HDU - 1150 : Machine Schedule(二分图、最小点覆盖)

题目链接:HDU - 1150 : Machine Schedule

题目大意:有A和B两台机器,A有n种工作模式,B有m种工作模式,现在有k个任务,每个任务可以被A的第x种模式执行,也可以被B的第y种模式执行,机器的初始工作状态在0模式,但是机器每换一种工作模式就需要重启一次,现在请你合理为机器安排任务,使得重启次数最少

题目分析:这里我们把每个任务看成一条边,A机器的每个模式看成cx的节点,B机器的每个模式看成cy的节点,这样就构成了一个二分图,题目要求重启次数最少,也即使用不同模式的次数最少,由此转化为最小点覆盖问题,由二分图性质可知,最小点覆盖数=最大匹配数,题目有个坑,就是注意机器的初始模式已经设定为0模式,因此与0模式相连的任务不能作为边。

AC代码:

//匈牙利算法

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=110;
int graph[maxn][maxn],vis[maxn];//图G和增广路访问标记
int match[maxn];//左边元素对应右边的匹配
int nx,ny,m;//左边点数,右边点数,边数

bool find_path(int u)//找增广路
{
    for(int i=0; i<ny; i++)
    {
        if(graph[u][i] && !vis[i])//不在增广路
        {
            vis[i]=1;//放进增广路
            if(match[i]==-1 || find_path(match[i]))//判断cy[i]是否匹配过,如果匹配过,则试图更改它之前的匹配项
            {//用dfs搜索,如果之前的匹配项能另外还存在增广路,则这里可以匹配u
                match[i]=u;
                return true;
            }
        }
    }
    return false;
}

int max_match()
{
    int res=0;
    memset(match,-1,sizeof(match));
    for(int i=0; i<nx; i++)
    {
        memset(vis,0,sizeof(vis));
        if(find_path(i)) res++;
    }
    return res;
}


int main()
{
    while(scanf("%d",&nx)==1 && nx)
    {
        scanf("%d%d",&ny,&m);
        memset(graph,0,sizeof(graph));
        for(int i=1; i<=m; i++)
        {
            int id,x,y;
            scanf("%d%d%d",&id,&x,&y);//本题的x,y编号是从0开始
            if(x && y) graph[x][y]=1;//注意,机器的起始状态处于0模式,故不能算作一次
        }
        printf("%d\n",max_match());
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值