题意

在一个工厂,有两台机器\(A, B\)生产产品。\(A\)机器有\(n\)种工作模式(模式\(0\),模式\(1\)……模式\(n-1\))。\(B\)机器有\(m\)种工作模式(模式\(0\),模式\(1\)……模式\(m-1\))。现要加工k个产品,每个产品可以由两台机器特定的模式生产,如产品0,可以由A机器在3号模式或B机器4号模式生产。两台机器初始模式都在模式0,但是,这两台机器不是很先进,如果需要切换模式,只能由人手工切换模式,手工切换可以切换到任意模式。求加工完k个产品需要切换模式的最少次数。(生产产品的顺序可以任意)

分析

如何建模?把A、B机器的模式抽象成点,然后把每个产品抽象成边,如果可以在\((A_i,B_j)\)下生产,建一条边(对于一个顶点为0的不建边)。然后求最少的点(模式)以覆盖所有的边(产品)。

于是成功的抽象成二分图的经典问题。

思考一下,为什么二分图的最小顶点覆盖能够通过二分图匹配来做。

  1. 首先,最小顶点覆盖数一定大于等于最大匹配数。不妨假设最大匹配为\(n\),那么一定有\(n\)条互不相邻的边,对这些边的覆盖至少要\(n\)个点。
  2. 上面考虑了匹配内的边/点。对于匹配范围外的节点,有两种情况:一种就是有边和匹配范围内元素相连但是没有匹配到,一种就是没边。对于第二种情况当作无事发生过,而对于第一种情况,有边的话这个边就和匹配范围的顶点打交道了,那这个顶点覆盖代表元素就又能够连接上匹配边,又能同非匹配边相连,这样,就不需要增加额外的顶点了。因此,我们有结论:匹配范围外的所有节点都不可能影响到最小顶点覆盖数,所以两者完全相等。

代码

这份代码会更为具体的解释相关细节。有错误欢迎指正,谢谢茄子。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define QUICKIO \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
#define MS(x,y) memset(x,y,sizeof(x))
using namespace std; bool mat[105][105],vis[105];
int n,m;
int link[105]; bool dfs(int x) //通过dfs拓展增广路,总是从左侧(u->v)开始。如果是个无向图的话,
{ //就不仅仅从左侧开始了,那种情况下的匹配要除以2。
rep(i,1,m)
{
if(mat[x][i] && !vis[i]) //有边,未拓展过
{
vis[i]=true;
if(link[i]==-1 || dfs(link[i])) //这个link[i]数组干什么吃的呢?用来标记i点走的上一个点的(邻接矩阵)。
{ //什么情况下会返回true?1. 从x点出发到的这个i点没被访问过(走了一条未匹配边)
link[i]=x; //2.i被访问过,有一条边(link[i]=>i),但是存在一条未访问边能够从link[i]走到其它地方
return true; //这样的情况下就是匹配边->未匹配边,发现增广路。这两种情况下找匹配。
} //而且对增广路的改进能够保证x点出发有边可以走,所以返回true的时候能够让答案++。
}
}
return false; // 这个点没法再构成增广路了,也就没法再改进匹配了。
} int hungary()
{
int ans=0;
rep(i,1,n)
{
ZERO(vis);
if(dfs(i)) ans++; //一个点只能够构成一个匹配
}
return ans;
} int main()
{
int k;
while(scanf("%d",&n)==1)
{
if(!n) break;
scanf("%d%d",&m,&k);
ZERO(mat);
ZERO(vis);
MS(link,-1);
rep(i,1,k)
{
int a,b,ti;
scanf("%d%d%d",&ti, &a, &b);
if(a && b) mat[a][b]=1;
}
printf("%d\n", hungary());
}
return 0;
}

「专题训练」Machine Schedule(HDU-1150)的更多相关文章

  1. 「专题训练」Collecting Bugs(POJ-2096)

    题意与分析 题意大致是这样的:给定一个\(n\times s\)的矩阵,每次可以随机的在这个矩阵内给一个格子染色(染过色的仍然可能被选中),问每一行和每一列都有格子被染色的次数的期望. 这题如果从概率 ...

  2. 「专题训练」游走(BZOJ-3143)

    题意与分析 定义走到每条边的期望为\(e_i\),一开始的想法是给定一个\(\large\sum_{i=1}^n e_i a_i\),求一个a的排列使得这个和最小.问题在于这样等于没对题目作分析,而且 ...

  3. 「专题训练」Hard problem(Codeforces Round #367 Div. 2 C)

    题意与分析 题意:给出\(n\)个字符串,可以反转任意串,反转每个串都有其对应的花费\(c_i\).经过操作后是否能满足字符串\(\forall i \in [1,n] \text{且} i \in ...

  4. 「专题训练」k-Tree(CodeForces Round #247 Div.2 C)

    题意与分析(Codeforces-431C) 题意是这样的:给出K-Tree--一个无限增长的树,它的每个结点都恰有\(K\)个孩子,每个节点到它\(K\)个孩子的\(K\)条边的权重各为\(1,2, ...

  5. 「专题训练」Boredom(CodeForces Round #260 Div.1 A)

    题意(Codeforces-455A) 给你\(n\)个数,你每次可以选择删除去一个数\(x\)获得\(x\)分,但是所有为\(x+1\)和\(x-1\)的数都得删去.问最大获得分数. 分析 这是一条 ...

  6. 「专题训练」Air Raid(HDU-1151)

    题目 在一个城市里有\(n\)个地点和\(k\)条道路,道路是无环的(也就是说一定可以二分染色--回路长度为偶数0),现在伞兵需要去n个地点视察,只能沿着路的方向走,问最少需要多少伞兵. 分析 这是什 ...

  7. hdu 1150 Machine Schedule hdu 1151 Air Raid 匈牙利模版

    //两道大水……哦不 两道结论题 结论:二部图的最小覆盖数=二部图的最大匹配数 有向图的最小覆盖数=节点数-二部图的最大匹配数 //hdu 1150 #include<cstdio> #i ...

  8. 「专题总结」LCT 2

    差不多理解板子之后,写了一些奇怪的题. 但是还是那个问题:树剖真好使. 魔法森林:mikufun说这个是傻逼题. 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐士. 魔法森林可以 ...

  9. 「日常训练」「小专题·图论」Domino Effect(1-5)

    题意 分析 这题几乎就是一条dijkstra的问题.但是,如何考虑倒在中间? 要意识到这题求什么:单源最短路的最大值.那么有没有更大的?倒在中间有可能会使它更大. 但是要注意一个问题:不要把不存在的边 ...

随机推荐

  1. Vue点击切换class

    <style> .active{ color: red; } </style> <ul id="app"> <li v-for='(ite ...

  2. vue - 简单实例(vue-router + webpack + vuex)

    分享 + 实践  基于公司部分产品技术栈转型使用vue,部分同事需要学习一下,快速上手,那么我很荣幸的成为了给大家分享vue技术栈的‘ ’导师‘,在这里我分享一下: 讲解大纲为:(我是有一份PPT的, ...

  3. 一. Selenium介绍

    1. 什么是Selenium 是web自动化测试工具集,主要包括:IDE.Grid.RC(Selenium1.0).WebDriver(Selenium2.0) 与其他工具的不同: 一般的脚本测试工具 ...

  4. MBTiles 离线地图演示 - 基于 Google Maps JavaScript API v3 + SQLite

    MBTiles 是一种地图瓦片存储的数据规范,它使用SQLite数据库,可大大提高海量地图瓦片的读取速度,比通过瓦片文件方式的读取要快很多,适用于Android.IPhone等智能手机的离线地图存储. ...

  5. javascript返回顶部插件+源码

    javascript插件->returnTop.js: /* ** 插件名称returnTop.js ** 调用返回头部单例参数说明 ** 调用方式:turn.init(ele,speed); ...

  6. java 时间日期

    Java 日期时间 java.util 包提供了 Date 类来封装当前的日期和时间. Date 类提供两个构造函数来实例化 Date 对象. 第一个构造函数使用当前日期和时间来初始化对象. Date ...

  7. C#的常用类

    BitConverter类:用于将源类型转换成字节数组,或者将字节数组转换成目标类型.在解决不同设备之间产生的大小端问题时,经常使用. Convert类:用于基本数据类型(包括Boolean/Byte ...

  8. 使用 Solr 构建企业级搜索服务器

    最近因项目需要一个全文搜索引擎服务, 在考察了Lucene及Solr后,我们选择了Solr. 本文简要记录了基于Solr搭建一个企业搜索服务器的过程.网上的资料太多千篇一律,也可能版本不同,总之在参照 ...

  9. MongoTemplate复合条件查询

    分. 排序.按时间查询 Query query = new Query();        //必须条件        Criteria c = Criteria.where("VINID& ...

  10. wireshark利用正则表达式过滤http协议中的jpg png zip等无用的数据包

    主要工具:小度随身wifi热点 + wireshark抓包工具.(强烈不建议使用360的产品,非常垃圾,而且干扰代理#墙IP,搞得你不能***) 利用wireshark这个强大的协议分析利器.去分析某 ...