HDU 3605 Escape (网络流,最大流,位运算压缩)
HDU 3605 Escape (网络流,最大流,位运算压缩)
Description
2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scientists want your help, is to determine what all of people can live in these planets.
Input
More set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. Here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet.
The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most..
0 <= ai <= 100000
Output
Determine whether all people can live up to these stars
If you can output YES, otherwise output NO.
Sample Input
1 1
1
1
2 2
1 0
1 0
1 1
Sample Output
YES
NO
Http
HDU:https://vjudge.net/problem/HDU-3605
Source
网络流,最大流,位运算压缩
题目大意
有n个人和m个星球,每一个人可以适应若干个星球的环境,而每一个星球都有人数上限。现在求能否让所有人都分配到一个其可以适应环境的星球上去。
解决思路
首先如果不管数据范围,这道题的网络流建模还是比较好想的。从源点出发连上所有的人,容量为1,从每一个人连边到其所有能适应的星球,容量为1,再从星球连边到汇点,容量为星球能容纳的人数上限。跑最大流后看看最大流是否与人数相等,如果相等则存在可行解,否则无解。
但要注意到本题的数据范围。人数有100000,这样直接跑最大流是会出问题的。再看一看m的数据范围,诶……只有10。于是我们可以想到一定有非常多的人,他们对所有星球的适应情况是一样的。所以我们可以用位运算的方式,把每一个人对星球的适应情况压缩在一个整数里面,然后统计这个数相同的人的人数,相当于把这些人都看作一个人。然后连边的时候就不是连所有的人,而是连不同的类型,而容量就是这种类型的人的个数,其他建图不变。
另:这里使用Dinic实现最大流,可以参考这篇文章
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int maxN=100101;
const int maxM=maxN*70;
const int inf=2147483647;
class Edge
{
public:
int u,v,flow;
};
int n,m;
int cnt;
int tot;
int Head[maxN];
int Next[maxM];
Edge E[maxM];
int depth[maxN];
int cur[maxN];
int Q[maxN];
map<int,int> Cnt;
void Add_Edge(int u,int v,int flow);
bool bfs();
int dfs(int u,int flow);
int main()
{
while (cin>>n>>m)
{
cnt=-1;
tot=0;
memset(Head,-1,sizeof(Head));
Cnt.clear();
for (int i=1;i<=n;i++)
{
int ret=0;
for (int j=1;j<=m;j++)
{
int is;
scanf("%d",&is);
ret=ret+(is<<j);//位运算统计
}
Cnt[ret]++;//Cnt就是统计某一种类型的人有多少个
}
map<int,int>::iterator loop;
for (loop=Cnt.begin();loop!=Cnt.end();loop++)//遍历所有的类型
{
tot++;
for (int i=1;i<=m;i++)//连人与星球
if ((loop->first)&(1<<i))//若这类人都能适应第j个星球,则连边,注意容量为这类人的个数
Add_Edge(tot,Cnt.size()+i,loop->second);
Add_Edge(0,tot,loop->second);//连源点与这类人
}
for (int i=1;i<=m;i++)
{
int flow;
scanf("%d",&flow);//读入每一个星球的人数上限,并连汇点
Add_Edge(tot+i,tot+m+1,flow);
}
int Ans=0;//求解最大流
while (bfs())
{
for (int i=0;i<=tot+m+1;i++)
cur[i]=Head[i];
while (int di=dfs(0,inf))
Ans+=di;
}
if (Ans==n)//若满流,则有解,否则无解
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
void Add_Edge(int u,int v,int flow)
{
cnt++;
Next[cnt]=Head[u];
Head[u]=cnt;
E[cnt].u=u;
E[cnt].v=v;
E[cnt].flow=flow;
cnt++;
Next[cnt]=Head[v];
Head[v]=cnt;
E[cnt].u=v;
E[cnt].v=u;
E[cnt].flow=0;
}
bool bfs()
{
memset(depth,-1,sizeof(depth));
int h=1,t=0;
Q[1]=0;
depth[0]=1;
do
{
t++;
int u=Q[t];
for (int i=Head[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((depth[v]==-1)&&(E[i].flow>0))
{
depth[v]=depth[u]+1;
h++;
Q[h]=v;
}
}
}
while (h!=t);
if (depth[tot+m+1]==-1)
return 0;
return 1;
}
int dfs(int u,int flow)
{
if (u==tot+m+1)
return flow;
for (int &i=cur[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((depth[v]==depth[u]+1)&&(E[i].flow>0))
{
int di=dfs(v,min(flow,E[i].flow));
if (di>0)
{
E[i].flow-=di;
E[i^1].flow+=di;
return di;
}
}
}
return 0;
}
HDU 3605 Escape (网络流,最大流,位运算压缩)的更多相关文章
- Hdu 3605 Escape (最大流 + 缩点)
题目链接: Hdu 3605 Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...
- HDU 3605 Escape(状压+最大流)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Sub ...
- HDU 3605 Escape 最大流+状压
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others) ...
- hdu 3605 Escape 二分图的多重匹配(匈牙利算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others) ...
- HDU 3605 Escape(状态压缩+最大流)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所 ...
- HDU - 3605 Escape (缩点+最大流/二分图多重匹配)
题意:有N(1<=N<=1e5)个人要移民到M(1<=M<=10)个星球上,每个人有自己想去的星球,每个星球有最大承载人数.问这N个人能否移民成功. 分析:可以用最大流的思路求 ...
- HDU 3605 Escape 最大流
题意: 如果这是2012年世界末日怎么办?我不知道该怎么做.但是现在科学家们已经发现,有些星球上的人可以生存,但有些人却不适合居住.现在科学家们需要你的帮助,就是确定所有人都能在这些行星上生活.输入多 ...
- hdu 1885 Key Task(bfs+位运算)
题意:矩阵中'#'表示墙,'.'表示通路,要求从起点'*'到达终点'X',途中可能遇到一些门(大写字母),要想经过,必须有对应的钥匙(小写字母).问能否完成,若能,花费的时间是多少. 分析:同hdu ...
- hdu 3572 Escape 网络流
题目链接 给一个n*m的图, 里面有一些点, '.'代表空地, '#'代表墙, 不可以走, '@'代表大门, 可以有多个, 'X'代表人, 问所有人都走出大门需要的最短时间, 每一时刻一个格子只能有一 ...
随机推荐
- SpringBoot日记——分布式篇
思考:什么是分布式?什么是微服务? 一些概念:RPC-远程过程调用,某台机器想要调用另一台机器所需要的一种服务,及分布式的服务框架,比如dubbo或者SpringCloud. 铺天盖地的分布式互联网系 ...
- OSGI的WEB开发环境搭建
第一步,搭建OSGI环境: 打开eclipse,点击run->run configration..,配置如下,点击run. 运行结果如下图所示:说明OSGI环境搭建完毕. 第二步:搭建基于OSG ...
- 生产者消费者模式 php 【转】
在工作中常常听到某某大牛之间的交谈会涉及到,xx消费者啊啥的,到底什么大牛之间讲的是什么? 这篇文章主要解决三个问题: 1.到底什么是生产者和消费者,以及它们之间的故事 2.它们之间靠什么交流 3.应 ...
- B. Divisor Subtraction
链接 [http://codeforces.com/contest/1076/problem/B] 题意 给你一个小于1e10的n,进行下面的运算,n==0 结束,否则n-最小质因子,问你进行多少步 ...
- M1/M2总结
在团队项目中,我是dev之一,负责的部分主要是排序部分. 应该说在团队中大家都各司其职,尤其是PM在组织方面也费了很多心思. 当然我个人因为空间上的距离和团队的联系不是那么密切…… 如同老师所言,这是 ...
- qa_model
[code=python] import os import sys import time import numpy import shelve import theano import thean ...
- 腾讯 xtestserver 基本使用教程~
刚刚简单录制了下 腾讯demo的基本测试脚本 成功~get新技能成功~开心ing~ 体验就是: 1.各种安卓机找开发者中心选项的usb调试模式太难找了.. 2.不管录制还是播放录制时都感觉好慢... ...
- Maven-Build Lifecycle(构建生命周期)
https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html https://www.w3cschoo ...
- MYSQL INDEX BTREE HASH
https://dev.mysql.com/doc/refman/5.6/en/index-btree-hash.html 译文:http://itindex.net/detail/54241-tre ...
- Selenium IDE 宏 试用 一例
本质是宏(Macro)理念 Marco概念的广泛应用: 1.Office的Excel里的任何操作的 可以都可以用VBA编程记录下宏,然后把记录的宏,可以回放.当然也可以生成代码,比如给Excel设置单 ...