2022牛客多校十 E-Reviewer Assignment(匈牙利算法)
题目链接:登录—专业IT笔试面试备考平台_牛客网
题目:
样例输入:
5 3
010
010
101
011
100
样例输出:
2 2 1 3 1
题意:给定n个人和m篇文章,然后给出一个n*m的矩阵,a[i][j]=1代表第i个人可以阅读第j篇文章,但是每个人最多只能阅读一篇文章,但是每篇文章可以被多个人阅读,问我们一种方案使得每篇文章被阅读次数不少于一次的文章数尽可能多,在此基础上要求文章被阅读次数不少于两次的 文章数尽可能多,依次类推,但是如果某个人不能阅读任何文章就直接输出-1.
分析:看到这道题目的第一反应就是匈牙利算法,也就是用于求解二分图最大匹配的算法,不知道匈牙利算法的小伙伴可以看下这里:二分图最大匹配(匈牙利算法)_AC__dream的博客-CSDN博客_二分图 最大匹配
如果理解匈牙利算法的思想的话应该就知道匈牙利算法是一个逐步尝试的算法,比如我们要为i进行匹配,但是发现i想匹配的对象已经被其他数匹配,那么我们就让与i想匹配的对象已经匹配的那个人去换一个对象进行匹配,如果能够成功就将其与另一个对象进行匹配,从而让i可以与其想匹配的对象进行匹配,否则不做处理,那么这样的话也就是说一旦某个数有了匹配对象,那么我们只是让其换一个对象进行匹配,并不会使其匹配的数目减少,所以这道题就利用了这一点,我们对文章数进行匹配,每个文章都尽可能地与人进行匹配,如果能匹配成功就直接匹配,否则就进行逐步尝试,我们用一个ans[i]记录阅读第i篇文章的人数,为了使得阅读每篇文章的人数都尽可能多,我们可以一遍一遍地尝试去用文章与人进行匹配,每篇文章最多被阅读的人就是n,这是显然的,所以我们最外层直接跑n次循环就可以了。但是我们需要加一个剪枝,也就是说如果某次循环中m篇文章都没有再次匹配成功直接退出就可以了,表面看起来这样复杂度非常高,但其实真正阅读一篇文章的人数不会特别多,这也就使得复杂度是够用的,需要注意的一点是最后我们要判断一下文章的总阅读次数是不是等于n,也就是判断是不是每个人都阅读了文章。
细节见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
const int N=403,M=2e5+10;
int h[N],ne[M],e[M],idx;
int match[N];//match[i]记录与右半部i号节点相匹配的左半部的节点编号
bool vis[N];//vis[i]标记第i个人有没有阅读文章
char s[N][N];
int ans[N];
void add(int x,int y)
{e[idx]=y;ne[idx]=h[x];h[x]=idx++;
}
bool find(int x)
{for(int i=h[x];i!=-1;i=ne[i]){int j=e[i];if(vis[j]) continue;vis[j]=true;if(match[j]==0||find(match[j])){match[j]=x;return true;}}return false;
}
int main()
{int n,m;cin>>n>>m;memset(h,-1,sizeof h);for(int i=1;i<=n;i++){scanf("%s",s[i]+1);for(int j=1;j<=m;j++)if(s[i][j]=='1') add(j,i);}int t=0;for(int i=1;i<=n;i++)//每篇文章的最多阅读次数{bool flag=false;for(int j=1;j<=m;j++){memset(vis,false,sizeof vis);if(find(j)){t++;ans[j]++;flag=true;}}if(!flag) break;}if(t==n)for(int i=1;i<=n;i++)printf("%d ",match[i]);elseprintf("-1");return 0;
}
2022牛客多校十 E-Reviewer Assignment(匈牙利算法)相关推荐
- 2022牛客多校(十)
2022牛客多校(十) 一.比赛小结 比赛链接:"蔚来杯"2022牛客暑期多校训练营10 二.题目分析及解法(基础题) F.Shannon Switching Game? 题目链接 ...
- (2022牛客多校五)H-Cutting Papers(签到)
样例输入: 2022 样例输出: 3649785.912339927 题意:求|x|+|y|+|x+y|<=n所在的区域和x*x+y*y=(n/2)*(n/2)所在区域的面积并. 这道题就是一个 ...
- [manacher][hash]Magic Spells 2022牛客多校第9场 G
题目描述 One day in the magic world, the young wizard RoundDog was learning the compatibility of spells. ...
- 2022牛客多校联赛第九场 题解
比赛传送门 作者: fn 目录 签到题 A题 Car Show / 车展 基本题 B题 Two Frogs / 两只青蛙 进阶题 G题 Magic Spells / 魔法咒语 签到题 A题 Car S ...
- 2022牛客多校 C Grab the Seat!
题意 二维平面,屏幕是 (0, 1)–(0, m) 的线段 有 n 行 m 列座位在屏幕前面,是坐标范围 1 ≤ x ≤ n, 1 ≤ y ≤ m 的整点 有 k 个座位已经有人,求出到屏幕的视线不被 ...
- [构造]Array 2022牛客多校第6场 A
题目描述 Ranran has a sequence aaa of nnn integers a1,a2,⋯ ,ana_1, a_2, \cdots, a_na1,a2,⋯,an which s ...
- 2022牛客多校2题解报告(同步自语雀)
一.赛后总结 总结就是缺乏清晰的大脑,当然一切的一切归因于实力不足. 开局看K,半个小时推出DP式子,交了就WA.差错没查出来,写了暴力对拍,就去看D了.后来拍了3个小时也没出问题...可能是数据生成 ...
- 2022牛客多校第一场A、C、D、G、I、J
A- Villages: Landlines 题意: 在一条横轴上给定nnn个点横坐标xsx_sxs和半径rsr_srs,可以在横轴上任意两点连线,问连接这nnn个点形成的圆的连线最小长度为多少. ...
- 【2022牛客多校第六场 Z题 Game on grid】dp
题目描述 输入描述 2 3 3 -B -B BB. 1 3 - 输出描述 no no yes no yes no 题意 有一个n*m的棋盘,Alice和Bob轮流进行操作,每操作一步都是从当前点到右边 ...
最新文章
- 云计算赋能人工智能,未来的红利在哪?
- WMI使用技巧集 C#
- 网页设计图片向上浮动_果冻公开课第六课:5分钟理解浮动布局
- Linux基础(1)--Vim编辑器的常用命令
- orcale建表,创建字段id使其自增
- opencv python 实现灰度图像和彩色图像直方图全局均衡化和自适应均衡化
- 【精华】多目标跟踪MOT
- RGB色彩模式-最广的颜色系统之一
- 学生管理系统——数据库表设计
- 完善智慧办公建设,小熊U租获京东数千万元A+轮融资
- failed with status 128
- 合成游戏中的数学原理
- 海瑞——一个奇特的人
- JavaWeb 图书推荐
- 嵌入式Linux MIPI接口LCD调试-关于DRM显示与应用调试的干货浓缩
- HTTP协议和URLConnection使用
- ESP32设备驱动-SHT30温度湿度传感器驱动
- 计算机系统i3和i6区别,英特尔内核迭代,有i3 i5 i7,没有i4 i6吗?
- 计网第四章 网络层(咕咕咕)
- .hive-staging_hive文件产生原因
热门文章
- 拓嘉启远电商:拼多多限时折扣计入最低价吗?
- html放百度首页,百度为什么要把你的网站放到首页?
- promise笔记(二)
- 记录报错日志——Log4j方式
- mac远程连接mysql
- GAMES101-现代计算机图形学学习笔记(6)作业5
- 解决free():invalid pointer:0x00000000000000155455 ****的问题。
- 数组的flat()方法
- NSA Tools Windows清单
- coredns status: CrashLoopBackOff