http://acm.hdu.edu.cn/showproblem.php?pid=3605

题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,“Y”or"N"。问是否可以全部人都顺利到自己想去的星球。

思路:很“有趣”的一道题目,n是1e5的大小,m只有10,没有想到状态压缩,看到n这么大肯定超时还是强行写了一波,于是RE(TLE)。想了挺久还是不会。看别人的思路是说二进制状态压缩。看到这就想到m只有10,于是可以分成1<<10 = 1024种情况,代表有这个选择,就相当于把人从1e5的大小强行压到1e3了。然后源点->选择->星球->汇点这样的图就建好了。源点->选择的边权是每种选择的人数,选择->星球的边权是对于每种选择,选择了这个星球的人数,星球->汇点的边权是星球容纳的人数。就酱了。Mark。

 #include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1200
#define NUM 1024
typedef long long LL;
struct Edge {
int v, nxt, cap;
Edge () {}
Edge (int v, int nxt, int cap) : v(v), nxt(nxt), cap(cap) {}
}edge[N*N*];
int tot, head[N], cur[N], pre[N], dis[N], gap[N], S, T, tol[]; void Add(int u, int v, int cap) {
edge[tot] = Edge(v, head[u], cap); head[u] = tot++;
edge[tot] = Edge(u, head[v], ); head[v] = tot++;
} void BFS() {
memset(dis, -, sizeof(dis));
memset(gap, , sizeof(gap));
queue<int> que;
while(!que.empty()) que.pop();
dis[T] = ; gap[]++; que.push(T);
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
Edge &e = edge[i];
if(dis[e.v] == -) continue;
dis[e.v] = dis[u] + ;
que.push(e.v);
gap[dis[e.v]]++;
}
}
} int ISAP(int n) {
BFS();
memcpy(cur, head, sizeof(cur));
int ans = , i, u = pre[S] = S;
while(dis[S] < n) {
if(u == T) {
int index, flow = INF;
for(i = S; i != T; i = edge[cur[i]].v)
if(flow > edge[cur[i]].cap)
flow = edge[cur[i]].cap, index = i;
for(i = S; i != T; i = edge[cur[i]].v)
edge[cur[i]].cap -= flow, edge[cur[i]^].cap += flow;
u = index;
ans += flow;
}
// puts("AAAA");
for(i = cur[u]; ~i; i = edge[i].nxt)
if(dis[edge[i].v] == dis[u] - && edge[i].cap > ) break;
// puts("BBBB");
if(~i) {
cur[u] = i; pre[edge[i].v] = u; u = edge[i].v;
} else {
if(--gap[dis[u]] == ) break;
int md = n;
for(i = head[u]; ~i; i = edge[i].nxt)
if(dis[edge[i].v] < md && edge[i].cap > ) cur[u] = i, md = dis[edge[i].v];
// puts("CCCC");
++gap[dis[u] = md + ];
// puts("ISAP");
u = pre[u];
}
}
return ans;
} int main() {
int n, m;
while(~scanf("%d%d", &n, &m)) {
memset(head, -, sizeof(head));
tot = ; S = NUM + m + , T = NUM + m + ;
int a; int dp[N][], s[N];
memset(dp, , sizeof(dp));
memset(s, , sizeof(s));
for(int i = ; i <= n; i++) {
int ss = ;
for(int j = ; j <= m; j++) {
scanf("%d", &a);
if(a) ss |= (a << (j - ));
}
s[ss]++;
for(int j = ; j <= m; j++) {
if(ss & ( << (j-))) dp[ss][j]++;
}
}
for(int i = ; i <= m; i++) scanf("%d", &tol[i]);
for(int i = ; i <= ; i++) {
Add(S, i, s[i]);
for(int j = ; j <= m; j++) {
if(dp[i][j]) {
Add(i, NUM + j, dp[i][j]);
}
}
}
for(int i = ; i <= m; i++) Add(NUM + i, T, tol[i]);
int ans = ISAP(T + );
if(ans == n) puts("YES");
else puts("NO"); }
return ;
}

HDU 3605:Escape(最大流+状态压缩)的更多相关文章

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

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

  2. HDU 3605 Escape 最大流+状压

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

  3. HDU 3605 Escape 最大流

    题意: 如果这是2012年世界末日怎么办?我不知道该怎么做.但是现在科学家们已经发现,有些星球上的人可以生存,但有些人却不适合居住.现在科学家们需要你的帮助,就是确定所有人都能在这些行星上生活.输入多 ...

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

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

  5. hdu 5025 Saving Tang Monk 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...

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

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

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

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

  8. HDU 1885 Key Task (BFS + 状态压缩)

    题意:给定一个n*m的矩阵,里面有门,有钥匙,有出口,问你逃出去的最短路径是多少. 析:这很明显是一个BFS,但是,里面又有其他的东西,所以我们考虑状态压缩,定义三维BFS,最后一维表示拿到钥匙的状态 ...

  9. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

随机推荐

  1. Tiddlywiki 维基程序使用手册

    文档 http://tiddlywiki.com/ http://web.nlhs.tyc.edu.tw/~lss/wiki/TiddlyWikiTutorialTW.html https://sit ...

  2. Selenium Webdriver java 积累一

    Selenium Webdriver 学习: http://jarvi.iteye.com/category/203994 https://github.com/easonhan007/webdriv ...

  3. java 4种方式读取配置文件 + 修改配置文件

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 方式一采用ServletContext读取读取配置文件的realpath然后通过文件流读取出来 方式二采用ResourceB ...

  4. android逆向代码分析截图

  5. OC中的字典

    // ********************不可变最字典***************** /* NSDictionary * dic = [NSDictionary dictionaryWithO ...

  6. 使用"关键词"来整理自己的知识库

    以前一直使用MyBase作为整理知识的工具,但是用到后来发现,当整理的知识越来越多时,树形目录的节点个数就会变得越来越庞大,层次越来越深,反而很难定位要查看或编辑的知识.最近发现使用"关键字 ...

  7. swift:谈谈swift几种常见属性的区别

    一.前奏 Swift作为一门新语言,经过几年的发展,逐渐趋于完善,目前已经更新到3.0版本,它汇集许多其他语言的特点,例如JS.Paython.C++等,完全区别于OC.个人感觉它没有完全的OOP和O ...

  8. hive 搭建

    Hive hive是简历再hadoop上的数据库仓库基础架构,它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储,查询和分析存储再hadoop种的大规模数据机制,hive定 ...

  9. svn 架设

    1.yum install subversion  openssl-devel -y 2. cd /data/svn 3. svnadmin create remote 4. 编辑conf 下 aut ...

  10. Redhat 7 或者 CentOS 7 密码破解

    1.在如下界面按 e 2.在 linux16 这一行的最后面添加 rd.break,然后按 ctrl + x 进入单用户模式 3.以读写的方式重新挂载 sysroot 4.切换到 sysroot 目录 ...