Escape

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

Problem 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
 

Source

 
由于n很大,直接建图会T,但是m很小,因此根据一个人在能否在m个星球上生存的状态,可以压缩为一个m位二进制数。最多有2^10种状态。
源点向每一种状态连边,容量为该状态的人数。
每个状态向该状态下能够生存的星球连边,容量为该状态的人数。
每个星球向汇点连边,容量为星球最多能承受的人数。
 //2017-08-24
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue> using namespace std; const int N = ;
const int M = ;
const int INF = 0x3f3f3f3f;
int head[N], tot;
struct Edge{
int next, to, w;
}edge[M]; void add_edge(int u, int v, int w){
edge[tot].w = w;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++; edge[tot].w = ;
edge[tot].to = u;
edge[tot].next = head[v];
head[v] = tot++;
} struct Dinic{
int level[N], S, T;
void init(int _S, int _T){
S = _S;
T = _T;
tot = ;
memset(head, -, sizeof(head));
}
bool bfs(){
queue<int> que;
memset(level, -, sizeof(level));
level[S] = ;
que.push(S);
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
int w = edge[i].w;
if(level[v] == - && w > ){
level[v] = level[u]+;
que.push(v);
}
}
}
return level[T] != -;
}
int dfs(int u, int flow){
if(u == T)return flow;
int ans = , fw;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to, w = edge[i].w;
if(!w || level[v] != level[u]+)
continue;
fw = dfs(v, min(flow-ans, w));
ans += fw;
edge[i].w -= fw;
edge[i^].w += fw;
if(ans == flow)return ans;
}
if(ans == )level[u] = -;
return ans;
}
int maxflow(){
int flow = , f;
while(bfs())
while((f = dfs(S, INF)) > )
flow += f;
return flow;
}
}dinic; char str[N];
int status[<<];//status[S]表示状态为S的人数,例如S=1010,表示可以在2号和4号星球上生存(从低位标号) int main()
{
std::ios::sync_with_stdio(false);
//freopen("inputM.txt", "r", stdin);
int n, m;
while(cin>>n>>m){
int s = , t = n+m+;
dinic.init(s, t);
int w;
memset(status, , sizeof(status));
for(int i = ; i <= n; i++){
int tmp = ;
for(int j = ; j <= m; j++){
tmp <<= ;
cin>>w;
tmp |= w;
}
status[tmp]++;
}
for(int i = ; i <= (<<); i++){
if(status[i]){
add_edge(s, i, status[i]);
for(int j = ; j <= m; j++){
if(i & (<<(j-)))
add_edge(i, n+j, status[i]);
}
}
}
int sum = ;
for(int i = ; i <= m; i++){
cin>>w;
sum += w;
add_edge(n+i, t, w);
}
if(sum < n){
cout<<"NO"<<endl;
continue;
}
if(dinic.maxflow() == n)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return ;
}

HDU3605(KB11-M 状态压缩+最大流)的更多相关文章

  1. Escape(状态压缩+最大流,好题)

    Escape http://acm.hdu.edu.cn/showproblem.php?pid=3605 Time Limit: 4000/2000 MS (Java/Others)    Memo ...

  2. HDU3605:Escape(状态压缩+最大流)

    Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  3. HDU 3605 Escape(状态压缩+最大流)

    http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所 ...

  4. Codeforces 1383F - Special Edges(状态压缩+最大流)

    Codeforces 题目传送门 & 洛谷题目传送门 首先暴力显然是不行的,如果你暴力最大流过了我请你吃糖 注意到本题的 \(k\) 很小,考虑以此为突破口解题.根据最大流等于最小割定理,点 ...

  5. hdu3605(最大流+状态压缩)

    传送门:Escape 题意:给出每个人适合住的星球信息和该星球能住多少人 ,第一行给出n m 代表有 n 个人 m 个星球,然后接下来n行每行m个数字 1代表适合第 i 个星球 0 代表不适合第 i ...

  6. HDU 3605:Escape(最大流+状态压缩)

    http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,"Y" ...

  7. hdu1565 网络流或状态压缩DP

    对于网络流有一个定理: 最小点权覆盖集=最大网络流: 最大点权独立集=总权值-最小点权覆盖集: 网络流解法代码如下: #include<cstdio> #include<iostre ...

  8. POJ 3254. Corn Fields 状态压缩DP (入门级)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Descr ...

  9. [HDU 4336] Card Collector (状态压缩概率dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 题目大意:有n种卡片,需要吃零食收集,打开零食,出现第i种卡片的概率是p[i],也有可能不出现卡 ...

随机推荐

  1. WebRTC开发基础(WebRTC入门系列2:RTCPeerConnection)

    RTCPeerConnection的作用是在浏览器之间建立数据的“点对点”(peer to peer)通信. 使用WebRTC的编解码器和协议做了大量的工作,方便了开发者,使实时通信成为可能,甚至在不 ...

  2. Vue2.5开发去哪儿网App 城市列表开发之 兄弟组件间联动及列表性能优化

    一,  兄弟组件间联动 1.  点击城市字母,左侧对应显示 给遍历的 字母 添加一个点击事件: Alphabet.vue @click="handleLetterClick" ha ...

  3. 解决ubuntu安装系统默认没有创建root用户

    安装ubuntu操作系统的时候,默认没有设置root账户的步骤!!! 这样在操作系统安装完成之后,就没有root用户, 一般,当前的普通用户,如果需要执行一些命令的时候,只要在命令前边加上sudo就行 ...

  4. 【原创】关于程序卸载的一个Bug

    今天解决了一个问题,程序安装目录下的某个文件不能被卸载,干净环境下不能重现,某些计算机可以重现. 解决: 这个问题里有两个文件不能被卸载 1.由程序生成的文件,如日志,即不是通过安装包安装的文件在卸载 ...

  5. 封了1000多个IP地址段,服务器现在坚如磐石,对付几个小毛贼还是很轻松的

    封了1000多个IP地址段,服务器现在坚如磐石 root登陆权限取消,防火墙装上,关闭所有没必要的端口,外层加装路由器映射, 修改常用端口,将常用端口改成陷阱程序,只要访问我这些陷阱端口,程序直接dr ...

  6. Spark集群测试

    1. Spark Shell测试 Spark Shell是一个特别适合快速开发Spark原型程序的工具,可以帮助我们熟悉Scala语言.即使你对Scala不熟悉,仍然可以使用这一工具.Spark Sh ...

  7. mac下安装rzsz

    1.先安装item2,item2 市类似mac风格的终端 item2 下载地址,http://iterm2.com/downloads.html,下载后解压缩就能运行 2.Install Homebr ...

  8. Spark中的常用算子

    更多有用的例子和算子讲解参见: http://homepage.cs.latrobe.edu.au/zhe/ZhenHeSparkRDDAPIExamples.html map是对每个元素操作, ma ...

  9. .Net 鉴权授权

    在这里总结一下工作中遇到的鉴权和授权的方法 ① 固定token的方案 通过在nginx或者代码中写死token,或者通过在限制外网访问的方式已来达到安全授权的方式 ② session方案 分布式会话方 ...

  10. CentOS 6.7 下 PostgreSQL 9.5 的安装与配置

    #yum方式安装(不同的系统版本对应的版本也不同) yum install postgresql-server #安装指定版本 yum install https://download.postgre ...