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. 

InputMore 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 
OutputDetermine 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 题目大意:就是星球移民,不同的人对不同的星球适应情况不同,给你m个人n个星球和每个人对星球的适应情况,和每一个星球最大承载人数,让你求是否可以全部成功移民。

这个题目是一个比较明显的网络流,但是dinic的复杂度是n*n*m,所以这个直接跑网络流肯定会超时。
然后我就T了,虽然知道自己超时了,不过并没有想到怎么解决。
然后搜题解,就看到了状态压缩。
就是因为m=10,所以可以去考虑可能有些人对星球的适应情况是一样的,这个要用二进制的方式去转化
怎么个状态压缩呢?

就是因为可能有些人对星球的适应情况完全相同,所以就把人对星球的适应状况压缩成只含有01的数字。
然后用map存储,这个之后就是建图了,
建图你只要知道,你只需要利用map的数据建图就可以了,建好图map数组就没什么用了,所以你不需要一个对应关系。

这个建图就看代码吧。

这个卡cin

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
#include <vector>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + ;
typedef long long ll;
int s, t, n, m;
struct node
{
int from, to, cap, flow;
node(int from=,int to=,int cap=,int flow=):from(from),to(to),cap(cap),flow(flow){}
};
vector<node>e;
vector<int>G[maxn];
void add(int u,int v,int c)
{
e.push_back(node(u, v, c, ));
e.push_back(node(v, u, , ));
int m = e.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
int level[maxn], iter[maxn];
void bfs(int s)
{
queue<int>que;
que.push(s);
memset(level, -, sizeof(level));
level[s] = ;
while(!que.empty())
{
int u = que.front(); que.pop();
for(int i=;i<G[u].size();i++)
{
node &now = e[G[u][i]];
if(now.cap>now.flow&&level[now.to]<)
{
level[now.to] = level[u] + ;
que.push(now.to);
}
}
}
} int dfs(int u,int v,int f)
{
if (u == v) return f;
for(int &i=iter[u];i<G[u].size();i++)
{
node &now = e[G[u][i]];
if(now.cap>now.flow&&level[now.to]>level[u])
{
int d = dfs(now.to, v, min(f, now.cap - now.flow));
if(d>)
{
now.flow += d;
e[G[u][i] ^ ].flow -= d;
return d;
}
}
}
return ;
}
map<int, int>mp;
int dinic()
{
int flow = ;
while()
{
bfs(s);
if (level[t] < ) return flow;
for (int i = s; i <= t; i++) iter[i] = ;
int f;
while ((f = dfs(s, t, inf)) > ) flow += f;
}
} void init()
{
for (int i = ; i <= n+m+; i++) G[i].clear();
e.clear();
mp.clear();
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
s = ;
for(int i=;i<=n;i++)
{
int ret = ;
for(int j=;j<=m;j++)
{
int x; scanf("%d", &x);
ret = ret + (x << j);
}
mp[ret]++;
}
int cnt = mp.size();
int num = ;
map<int, int>::iterator p;
for(p=mp.begin();p!=mp.end(); p++)
{
num++;
for(int i=;i<=m;i++)
{
if ((p->first)&( << i))
{
add(num, cnt + i, p->second);
}
}
add(s, num, p->second);
}
t = num + m + ;
for(int i=;i<=m;i++)
{
int x; scanf("%d", &x);
add(num + i, t, x);
}
int ans = dinic();
if (ans >= n) printf("YES\n");
else printf("NO\n");
}
return ;
}

网络流 E - Escape HDU - 3605的更多相关文章

  1. Escape HDU - 3605(归类建边)

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

  2. M - Escape - HDU 3605 - (缩点+最大流SAP)

    题目大意:2012世界末日来了,科学家发现了一些星球可以转移人口,不过有的人可以在一些星球上生存有的人不行,而且每个星球都有一定的承载量,现在想知道是否所有的人都可以安全转移呢? 输入:首先输入一个N ...

  3. HDU 3605 Escape (网络流,最大流,位运算压缩)

    HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...

  4. Hdu 3605 Escape (最大流 + 缩点)

    题目链接: Hdu 3605  Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...

  5. HDU 3605 Escape(状压+最大流)

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

  6. HDU 3605 Escape 最大流+状压

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others)    ...

  7. hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

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

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

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

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

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

随机推荐

  1. SQLServer之附加数据库

    附加数据库注意事项 必须首先分离数据库. 尝试附加未分离的数据库将返回错误. 附加数据库时,所有数据文件(MDF 文件和 LDF 文件)都必须可用. 如果任何数据文件的路径不同于首次创建数据库或上次附 ...

  2. 发布基于Orchard Core的友浩达科技官网

    2018.9.25 日深圳市友浩达科技有限公司发布基于Orchard Core开发的官网 http://www.weyhd.com/. 本篇文章为你介绍如何基于Orchard Core开发一个公司网站 ...

  3. Python爬虫9-request包介绍及应用

    GitHub代码练习地址:1.两种简单get请求方法:https://github.com/Neo-ML/PythonPractice/blob/master/SpiderPrac13_request ...

  4. git 建议使用

    1 登录github官网首页 创建一个项目 2 本地克隆下载git项目 git clone https://github.com/wangguoxingduanxuejing/branch-pract ...

  5. GC参考手册 —— GC 算法(实现篇)

    学习了GC算法的相关概念之后, 我们将介绍在JVM中这些算法的具体实现.首先要记住的是, 大多数JVM都需要使用两种不同的GC算法 —— 一种用来清理年轻代, 另一种用来清理老年代. 我们可以选择JV ...

  6. Redis学习笔记~分布锁的使用

    回到目录 分布锁主要用在多进程共同访问同一个资源时候,用来保持同一时间段只能有一个进程执行,同时避免了并发冲突的出现,这在很多场景都会用到,像秒杀库存,抽奖库存,多操作者处理一家公司等. void T ...

  7. 如何在linux下使用git管理上传代码&误删文件修复

    首先需要安装git,sudo apt-get install git,这时就可以下载代码了. 然后先在gituhub上新建一个仓库,然后先在本地建一个git目录,git init 然后再配置用户名和邮 ...

  8. SLAM+语音机器人DIY系列:(三)感知与大脑——6.做一个能走路和对话的机器人

    摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...

  9. leetcode math类型题目解题总结

    2. Add Two Numbers https://leetcode.com/problems/add-two-numbers/description/ class Solution { publi ...

  10. 程序猿想聊天 - 創問 4C 團隊教練心得(二)

    在第二天裡,主要談的是關於 Courage (勇氣) . Co-Create (共創) 的部分因為我們不是真實的團隊,就沒有繼續下去了 一早開始先回顧了一下前一天的內容,接下來我們就開始玩小遊戲 這個 ...