HDU
来源:互联网 发布:收集5条红酒网络广告语 编辑:程序博客网 时间:2024/06/05 04:50
题目链接: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;}
阅读全文
1 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 几个经典编程题(二)
- Presto安装
- Word2Vec笔记
- 深度学习方法:卷积神经网络CNN经典模型整理Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning
- QT关于程序运行日志
- HDU
- 获得当前周别所属年份
- Junit的基本使用
- HDU 4507 吉哥系列故事――恨7不成妻 数位DP
- 搭建fabric1.0的开发环境+e2e_cli例子的运行
- Java可变参数varargus的使用
- NG 逻辑回归_二分类
- JQ制作一个目录树菜单
- 用仿射变换实现图片旋转,很好用!