题目链接:点击查看

题目大意:到世界末日了,现在人们要逃离去其他的星球,现在给出n个人以及m个星球,再给出每个人可以前往的星球,最后给出每个星球的容量,题目问最多能让多少个人逃离

题目分析:这个题读完题看到的模型就是二分图多重匹配问题,然后想都没想直接建边跑网络流了,但果不其然的T掉了,毕竟n到了1e5的程度,所以我们必须想办法优化

因为m给的特别小,而且还是只有0或1组成,不难想到二进制,这样一来最多有2^10种逃离方案,我们不妨记录某种方案的人数,最后用方案数来建边,这样就能将1e5个点压缩到1e3个点了,具体建边方法就是:

  1. 超级源点与每一个状态建边,边权为当前状态的人数
  2. 每一个状态与相应的星球建边,边权为无穷大
  3. 每一个星球与超级汇点建边,边权为星球的容量

这里再解释一下为什么每一个状态与星球的边权为无穷大,因为我们不能确定某个状态到底向哪个特定的星球转移了多少个人,但是我们知道某个状态至多只有多少人,所以对于这些分支我们不好确定,所以就只能在源点到状态这条边上确定限制了

建好图之后直接跑模板就好了,最后判断一下最大流量是否等于总人数

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1100;struct Edge
{int to,w,next;
}edge[N*20];//边数int head[N],cnt,num[N];void addedge(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;//反向边边权设置为0edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],now[N*20];//深度 当前弧优化bool bfs(int s,int t)//寻找增广路
{memset(d,0,sizeof(d));queue<int>q;q.push(s);now[s]=head[s];d[s]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(d[v])continue;if(!w)continue;d[v]=d[u]+1;now[v]=head[v];q.push(v);if(v==t)return true;}}return false;
}int dinic(int x,int t,int flow)//更新答案
{if(x==t)return flow;int rest=flow,i;for(i=now[x];i!=-1&&rest;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(w&&d[v]==d[x]+1){int k=dinic(v,t,min(rest,w));if(!k)d[v]=0;edge[i].w-=k;edge[i^1].w+=k;rest-=k;}}now[x]=i;return flow-rest;
}void init()
{memset(num,0,sizeof(num));memset(head,-1,sizeof(head));cnt=0;
}int solve(int st,int ed)
{int ans=0,flow;while(bfs(st,ed))while(flow=dinic(st,ed,inf))ans+=flow;return ans;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int n,m;while(scanf("%d%d",&n,&m)!=EOF){init();int st=N-1;int ed=N-2;for(int i=1;i<=n;i++){int val=0;for(int j=0;j<m;j++){int x;scanf("%d",&x);val+=x*(1<<j);//维护二进制的状态}num[val]++;}for(int i=0;i<(1<<10);i++){if(!num[i])continue;addedge(st,i,num[i]);//源点-状态,边权为人数for(int j=0;j<10;j++)if(i&(1<<j))addedge(i,j+(1<<10),inf);//状态-星球,边权为无穷大}for(int i=0;i<m;i++){int val;scanf("%d",&val);addedge(i+(1<<10),ed,val);//星球-汇点,边权为星球容量}int ans=solve(st,ed);if(ans==n)printf("YES\n");elseprintf("NO\n");}return 0;
}

HDU - 3605 Escape(二分图多重匹配-网络流最大流+思维建边+状态压缩)相关推荐

  1. POJ - 3614 Sunscreen(贪心/二分图最大匹配-多重匹配/网络流-最大流)

    题目链接:点击查看 题目大意:给出n头奶牛,奶牛们现在要晒太阳,每头奶牛需要[l,r]区间内的光照强度,现在有m种防晒霜,每种防晒霜可以让奶牛接受到val数值的光照强度,然后每种防晒霜只有num个,现 ...

  2. POJ - 1698 Alice's Chance(二分图多重匹配-网络流)

    题目链接:点击查看 题目大意:爱丽丝要拍电影,现在有n部电影,每部电影都只能在每周特定的日期拍摄,并且需要拍摄d天,要在w周之内完成,现在问爱丽丝能否将所有的电影都拍摄完成 题目分析:因为每部电影可以 ...

  3. 网络流三·二分图多重匹配 HihoCoder - 1393

    网络流三·二分图多重匹配 HihoCoder - 1393 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int ma ...

  4. 网络流三·二分图多重匹配

    描述 学校的秋季运动会即将开始,为了决定参赛人员,需要统计分配比赛选手. 已知班级一共有N名学生,编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选 ...

  5. 【网络流24题】解题报告:E 、圆桌问题(最大流求二分图多重匹配)

    E .圆桌问题(最大流求二分图多重匹配)[省选/NOI- ] 可以直观的想到,二分图的左边是单位,右边是桌子 由于题目的限制 每个单位只能在一个桌子坐一个人 所以我们就把每个单位向各个桌子连一道流量为 ...

  6. 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)

    [题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个 满足要求的组卷算法. ...

  7. POJ - 3189 Steady Cow Assignment(二分图多重匹配)

    题目链接:点击查看 题目大意:给出n只奶牛以及m个牛棚,接下来给出一个n*m的矩阵,给出每一只奶牛对于每个牛棚的喜爱度,按照降序给出,从rank1到rankm,现在问如何分配牛棚能让所有奶牛中最高的r ...

  8. poj2112(floyd+二分+二分图多重匹配)

    (感觉是一个比较基础的二分图多重匹配) 题目意思大概就是有K个挤奶点,C个奶牛,一个挤奶点能容下M个奶牛,问如果所有奶牛都被放入挤奶点时,距离最远奶牛得最短距离(距离可以经过其他点) 首先看到可以经过 ...

  9. 图论:二分图多重匹配

    使用最大流和费用流解决二分图的多重匹配 之前编辑的忘存了好气啊.. 本来打算学完二分图的乱七八糟的匹配之后再去接触网络流的,提前撞到了 之前我们说的二分图最大匹配和二分图最大权匹配有一个特点,那就是没 ...

最新文章

  1. Android小项目之--前台界面与用户交互的对接 进度条与拖动条(附源码)
  2. C# 报警 控制蜂鸣器发声
  3. Error encountered when performing Introspect schema xxx 错误的解决方法
  4. 基于智能计算的降维技术研究与应用
  5. JVM(3)——JVM类加载器
  6. linux重启mysqlsystemctl_解决linux(centos7)重新安装mysql systemctl start mysqld.service时报错...
  7. [bash] 打包某目录(可以是绝对路径)下的指定扩展名的文件
  8. vue 1.0源代码重点难点分析
  9. c语言学习-有一12个元素的整型数组b,从键盘输入数据,请以每行4个数据各个数据之间空两格的形式输出b数组的12个元素
  10. Python机器学习 集成算法实例
  11. ASP.NET Web开发框架之八 所有ERP部分的源代码全部开放下载
  12. csdn上讲一个实时计算架构比较清晰的一篇文章
  13. “Python小屋”1300篇历史文章分类速查表
  14. Ubuntu 下搭建 GCC 交叉编译工具链
  15. 知乎 live 记录
  16. 恩智浦智能车主控板分享
  17. Linux学习笔记Day01-03 Xshell,Xfpt下载安装,使用
  18. python识别颜色并提取轮廓_用 Python 对图片主体轮廓进行提取、颜色标记、并计算区域面积...
  19. 什么是异地双活及应用场景
  20. 基于YOLOV5的目标检测模型-口罩检测

热门文章

  1. linux mysql UNSIGNED,关于mysql:MySqlint10-与-int-unsigned-之前的区别
  2. wordpress archive.php,哪个网址将导致wordpress使用archive.php?
  3. MySQL高级 - 案例 - AOP记录日志
  4. Nginx的Gzip和sendfile的共存问题
  5. 事务注解 @Transactional
  6. MyBatis 架构分层与模块划分
  7. 观察者模式在源码中的应用
  8. Spring-Cloud中的 熔断、限流、降级
  9. HDFS的API操作-获取FileSystem方式
  10. springboot的自动配置原理