机器任务-

欢迎大家访问博客:博客传送门

机器任务


题目描述

image-20210719155448461


核心思路

这一题其实是二分图最大匹配的应用。

结论:二分图的最小顶点覆盖=二分图的最大匹配

最小顶点覆盖:用最少的顶点来覆盖图中所有的边

二分图最小顶点覆盖的模型特点是:每条边有2个端点,二者至少选择一个。我们称之为“2要素”。如果一个题目具有“2要素”的特点,那么就可以尝试抽象成二分图最小顶点覆盖模型来求解

在这道题目中,每个任务要么在机器 A A A上以模式 a [ i ] a[i] a[i]执行,要么在机器 B B B上以模式 b [ i ] b[i] b[i]执行,二者必选其一。因此,我们可以把机器 A A A N N N种模式作为 N N N个顶点放在左部点集合中,把机器 B B B M M M种模式作为 M M M个顶点放在右部点集合中,每个任务当作是一条无向边,连接左边的 a [ i ] a[i] a[i]模式(第 a [ i ] a[i] a[i]个节点)和右边的 b [ i ] b[i] b[i]模式(第 b [ i ] b[i] b[i]个节点)。

由于每台机器转换一次模式就需要重启一次,要想使得重启次数最少,那么就需要某种模式它能处理多种任务,即一个节点能够连接多个无向边。那么要使重启次数最少,即用最少的顶点来覆盖掉所有的无向边。那么这就是要求二分图的最小顶点覆盖,根据前面的结论可知,只需要求出二分图的最大匹配即可。

这里有个坑点,两台机器一开始的模式都是0,因此每个任务如果可以在模式为0的情况下都可以直接进行,则不需要进行重启,因此建图时碰到 a [ i ] a[i] a[i]或者 b [ i ] b[i] b[i]为0,则直接跳过不考虑把它建立到图中即可。


代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110;
int n,m,k;
int match[N];
int g[N][N];
bool st[N];
bool find(int x)
{
    //遍历机器B中的这m个模式   即寻找右边的女生集合
    for(int i=0;i<m;i++)
    {
        //如果x这个男生还没有访问过i这个女生
        //并且 此时并不是处于模式0
        if(!st[i]&&g[x][i]==1)
        {
            st[i]=true;
            if(match[i]==-1||find(match[i]))
            {
                match[i]=x;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    while(scanf("%d",&n),n)
    {
        //有多组测试数据  因此每次都要进行初始化
        memset(match,-1,sizeof match);
        memset(g,0,sizeof g);
        scanf("%d%d",&m,&k);
        while(k--)
        {
            int id,a,b;
            scanf("%d%d%d",&id,&a,&b);
            //如果机器A处于模式0或者机器B处于模式0 那么g[a][b]=0;否则g[a][b]=1
            if(a&&b)
            g[a][b]=1;
        }
        int res=0;
        //机器A的n个模式看成是左边的男生集合  从男生集合出发进行匹配
        for(int i=0;i<n;i++)
        {
            memset(st,0,sizeof st);
            if(find(i))
            res++;
        }
        printf("%d\n",res);
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷心菜不卷Iris

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值