Acwing 376.机器任务 (最小点覆盖)

简介: 笔记

Acwing 376.机器任务


题意

有两台机器 A,B以及 K 个任务。


机器 A 有 N种不同的模式(模式0 ∼ N − 1 ),机器 B 有 M 种不同的模式(模式 0 ∼ M − 1)。


两台机器最开始都处于模式 0。


每个任务既可以在 A上执行,也可以在 B 上执行。


对于每个任务 i,给定两个整数a[i] 和b[i],表示如果该任务在A 上执行,需要设置模式为 a[i],如果在B 上执行,需要模式为b[i]。


任务可以以任意顺序被执行,但每台机器转换一次模式就要重启一次。


求怎样分配任务并合理安排顺序,能使机器重启次数最少。


思路

将机器A的所有模式看作左边的集合,机器B 的所有模式看作右边的集合,模式看作顶点,任务看作连接机器 A 和机器 B 的一条边,原题可以抽象成一个二分图。那么题目要求的就是,在这张二分图中最少选多少个顶点(模式),可以覆盖所有的边(任务),即最小点覆盖问题。 而我们又知道在二分图中 最小点覆盖 == 最大匹配数,所以直接用匈牙利算法求二分图的最大匹配即可。


需要注意的是,两台机器最初都处于模式0,所以不用转换模式即可将a[i] 或b[i] 为0的任务完成,所以建图时将这种情况忽略即可。


代码

// Author:zzqwtcc
// Problem: 机器任务
// Contest: AcWing
// Time:2021-10-07 14:17:44
// URL: https://www.acwing.com/problem/content/378/
// Memory Limit: 10 MB
// Time Limit: 1000 ms
#include<bits/stdc++.h>
#include<unordered_map>
// #define int long long
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define mod 1000000007
#define MOD 998244353
#define rep(i, st, ed) for (int (i) = (st); (i) <= (ed);++(i))
#define pre(i, ed, st) for (int (i) = (ed); (i) >= (st);--(i))
#define debug(x,y) cerr << (x) << " == " << (y) << endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
template<typename T> inline T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<typename T> inline T lowbit(T x) { return x & -x; }
// template<typename T> T qmi(T a, T b = mod - 2, T p = mod) { T res = 1; b %= (p - 1 == 0 ? p : p - 1); while (b) { if (b & 1) { res = (LL)res * a % p; }b >>= 1; a = (LL)a * a % p; }return res % mod; }
const int N = 110;
int n,m,k;
vector<int>vec[N];
bool st[N];
int match[N];
bool find(int u){
  for(int i =0 ; i < vec[u].size();++i){
    int j =vec[u][i];
    if(st[j])continue;
    st[j] = true;
    if(match[j] == -1 || find(match[j])){
      match[j] = u;
      return true;
    }
  }
  return false;
}
void solve() {
    while(cin >> n, n){
      for(int i = 0 ;i <= 100;++i)vec[i].clear();
      memset(match,-1,sizeof match);
      cin >> m >> k;
      while(k--){
        int id,u,v;cin >> id >> u >> v;
        if(u && v)
          vec[u].push_back(v);
      }
      int res = 0;
      for(int i = 0; i <= n;++i){
        memset(st,0,sizeof st);
        if(find(i))
          res++;
      }
      for(int i = 0; i <= m;++i){
          if(match[i] == 0){
              res--;
              break;
          }
      }
      cout << res << endl;
    }
}
signed main() {
    // int _; cin >> _;
    // while (_--)
        solve();
    return 0;
}


目录
相关文章
|
存储 安全 Unix
计算机操作系统课后习题答案(3)
7.试从检索速度和存储费用两方面对索引文件和索引顺序文件进行比较。 答:索引文件的主文件每条记录配置一个索引项,存储开销N,检索到具有指定关键字的记录,平均查找N/2条记录。对于索引顺序文件,每个记录分组配置一个索引项,存储开销为N,检
856 0
|
存储 算法 安全
计算机操作系统课后习题答案(2)
23.在生产者消费者问题中,如果缺少了signal(full)或signal(empty),对执行结果有何影响? 答: 如果缺少signal(full),那
626 0
|
存储 算法 安全
计算机操作系统课后习题答案(1)
第一章 1.设计现代OS的主要目标是什么? 答:(1)有效性 (2)方便性 (3)可扩充性 (4)开放性 2.OS的作用
145 0
《计算机操作系统【汤小丹】》课后习题答案(四)
《计算机操作系统【汤小丹】》课后习题答案(四)
73 0
《计算机操作系统【汤小丹】》课后习题答案(三)
《计算机操作系统【汤小丹】》课后习题答案(三)
72 0
《计算机操作系统【汤小丹】》课后习题答案(五)
《计算机操作系统【汤小丹】》课后习题答案(五)
101 0
《计算机操作系统【汤小丹】》课后习题答案(二)
《计算机操作系统【汤小丹】》课后习题答案(二)
111 0
《计算机操作系统【汤小丹】》课后习题答案(一)
《计算机操作系统【汤小丹】》课后习题答案(一)
99 0
《蓝桥杯每日一题》dfs·AcWing3502. 不同路径数
《蓝桥杯每日一题》dfs·AcWing3502. 不同路径数
66 0
|
C++
蓝桥杯练习题十 - 煤球数目(c++)
蓝桥杯练习题十 - 煤球数目(c++)
143 0
蓝桥杯练习题十 - 煤球数目(c++)