Escape

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 13271    Accepted Submission(s): 3351

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3605

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

题意:

给出n个人,m个星球,每个人都有自己能去的星球,每个星球都有一定的容量,问是否所有人都能到这m个星球上面去。

题解:

注意这里人数有1e5,而m不超过10。如果我们直接建边跑最大流,边数可能为1e6,这样肯定会超时的。

我们注意到m很小,那么会想到对状态进行压缩(如果之前接触过这类题)。

虽然人数很多,但是最多有2^10种状态,所以我们可以将1e5个点压缩为1024个点,这样再来建图就能在时间、空间上有较大的优化。

压缩后的每个点表示对这m个星球意愿的状态,1代表能去,0代表不能。

细节见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
#define INF 99999999
using namespace std;
typedef long long ll;
const int N = , M = ;
int n,m,cnt,tot,t;
int peo[N],head[N],d[N]; struct Edge{
int v,next,c;
}e[M];
void adde(int u,int v,int c){
e[tot].v=v;e[tot].c=c;e[tot].next=head[u];head[u]=tot++;
e[tot].v=u;e[tot].c=;e[tot].next=head[v];head[v]=tot++;
}
int bfs(){
memset(d,,sizeof(d));d[]=;
queue <int > q;q.push();
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(e[i].c> && !d[v]){
d[v]=d[u]+;
q.push(v);
}
}
}
return d[t]!=;
}
int dfs(int s,int a){
if(s==t || a==) return a;
int flow=,f;
for(int i=head[s];i!=-;i=e[i].next){
int v=e[i].v;
if(d[v]!=d[s]+) continue ;
f=dfs(v,min(a,e[i].c));
if(f>){
e[i].c-=f;
e[i^].c+=f;
flow+=f;
a-=f;
if(a==) break;
}
}
if(!flow) d[s]=-;
return flow;
}
int Dinic(){
int flow=;
while(bfs()) flow+=dfs(,INF);
return flow;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
cnt=tot=;memset(head,-,sizeof(head));
memset(peo,,sizeof(peo));
for(int i=;i<=n;i++){
int x = ;
for(int j=,op;j<=m;j++){
x<<=;
scanf("%d",&op);
x+=op;
}
if(!peo[x]) cnt++;
peo[x]++;
}
t=cnt+m+;
for(int i=;i<=m;i++){
int c;
scanf("%d",&c);
adde(cnt+i,t,c);
}
int p=;
for(int i=;i<(<<m);i++){
if(!peo[i]) continue ;
p++;
adde(,p,peo[i]);
for(int j=;j<m;j++)
if(i&(<<j)) adde(p,m-j+cnt,peo[i]);
}
int ans = Dinic();
if(ans==n) puts("YES");
else puts("NO");
}
return ;
}

最新文章

  1. 2 Unique Binary Search Trees II_Leetcode
  2. HDU 1817Necklace of Beads(置换+Polya计数)
  3. SQl server 关于重复插入数据的测试
  4. xml 解析
  5. Replace Nested Conditional with Guard Clauses(用卫语句代替嵌套循环)
  6. BibTex插入Reference
  7. Windows平台安装Redmine2.5.x
  8. 使用ASP.Net WebAPI构建REST服务(五)——客户端
  9. [FJSC2014]异或之
  10. [O] SQLite数据库报错:no such column
  11. MVC4相关Razor语法以及Form表单(转载)
  12. 从源码来理解slf4j的绑定,以及logback对配置文件的加载
  13. java String 不可变
  14. 序列化、反序列化(Serializable特性)
  15. 1089. Insert or Merge (25)
  16. C++头文件用&lt;&gt;还是“” 以及 要加.h还是不加 的问题
  17. api管理平台
  18. How to configure Samba Server share on Debian 9 Stretch Linux
  19. 洛谷P3724 大佬 [AH2017/HNOI2017] dp+bfs
  20. Spark(十七)图计算GraphX

热门文章

  1. print(__file__)返回&lt;encoding error&gt;的问题
  2. MetInfo最新网站漏洞如何修复以及网站安全防护
  3. 自己动手编写 Dockerfile 构建自定义的Jenkins
  4. 003---生成器 &amp; 迭代器
  5. react项目中引入百度地图打包报错问题
  6. java 第五章 方法定义及调用
  7. C++各种类型的简单排序大汇总~
  8. DDoS 攻击与防御:从原理到实践(下)
  9. 《.NET 微服务:适用于容器化 .NET 应用的体系结构》关键结论
  10. c++ constructor, copy constructor, operator =