HDU 3605:Escape(最大流+状态压缩)
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(最大流+状态压缩)的更多相关文章
- Hdu 3605 Escape (最大流 + 缩点)
题目链接: Hdu 3605 Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...
- HDU 3605 Escape 最大流+状压
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 3605 Escape 最大流
题意: 如果这是2012年世界末日怎么办?我不知道该怎么做.但是现在科学家们已经发现,有些星球上的人可以生存,但有些人却不适合居住.现在科学家们需要你的帮助,就是确定所有人都能在这些行星上生活.输入多 ...
- HDU 3605 Escape (网络流,最大流,位运算压缩)
HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...
- hdu 5025 Saving Tang Monk 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...
- HDU 3605 Escape(状压+最大流)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Sub ...
- hdu3605(最大流+状态压缩)
传送门:Escape 题意:给出每个人适合住的星球信息和该星球能住多少人 ,第一行给出n m 代表有 n 个人 m 个星球,然后接下来n行每行m个数字 1代表适合第 i 个星球 0 代表不适合第 i ...
- HDU 1885 Key Task (BFS + 状态压缩)
题意:给定一个n*m的矩阵,里面有门,有钥匙,有出口,问你逃出去的最短路径是多少. 析:这很明显是一个BFS,但是,里面又有其他的东西,所以我们考虑状态压缩,定义三维BFS,最后一维表示拿到钥匙的状态 ...
- HDU 3681 Prison Break(状态压缩dp + BFS)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...
随机推荐
- SqlServer 笔记二 获取汉字的拼音首字母
一.该函数传入字符串,返回数据为:如果为汉字字符,返回该字符的首字母,如果为非汉字字符,则返回本身. 二.用到的知识点:汉字对应的UNICODE值,汉字的排序规则. 三.数据库函数: )) ) AS ...
- 《实时控制软件设计》第一周作业 欧梓峰 U201317662 (更新)
CNC 插补计算程序分析 前言:插补(Interpolation),即机床数控系统依照一定方法确定刀具运动轨迹的过程.一般是已知起点坐标.终点坐标和轨迹,由数控插补计算程序实时的算出各个中间的坐标来拟 ...
- 如何用shared_ptr减少锁的争用
在并发环境下锁的使用是家常便饭, 如何减少锁的使用是优化程序性能的一个方面. c++11里面新增了智能指针std::shared_ptr, 这个东西也许能给我们带来些启发. shared_ptr的一个 ...
- ios程序发布测试打包
1. 获取测试机UDID 手机连接电脑,打开iTunes-摘要-点击序列号,设备概要界面显示设备udid-反键-拷贝 2. 添加设备 取得UDID后,进入开发者中心-iOS PRovisioning ...
- WP8.1 和UWP 如何使用下载网页的上的音频 并保存
WP8.1: private async Task<StorageFile> GetVoiceData() { HttpClient httpclient = new HttpClient ...
- sed 引入shell变量
双单引号即可 1.eval sed ’s/$a/$b/’ filename2.sed "s/$a/$b/" filename3.sed ’s/’$a’/’$b’/’ filenam ...
- JqGrid自定义的列
$("#gridTable").jqGrid({ //...其它属性 colModel: [ //...其它列 { name: 'dsource_alarm', index: 'd ...
- 调试一个socket通信bug的心理过程和反思
背景交代.最近在玩lua的服务端编码, 有项目A,B,AB都是同一个模子的.我手上有A的winsocket客户端和服务端的代码,B项目早期的一份linux下的lua client.服务端.客户端都是L ...
- C# 获取汉字拼音首字母
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 本节探讨C#获取汉字拼音首字母的方法: 代码类东西, ...
- 限制action所接受的请求方式或请求参数
原文:http://www.cnblogs.com/liukemng/p/3726897.html 2.限制action所接受的请求方式(get或post): 之前我们在HelloWorldContr ...