Hdu 3605 Escape (最大流 + 缩点)
题目链接:
题目描述:
有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功?
解题思路:
正常情况下建图,不会爆内存,但是TLE还是稳稳的。以前只遇到过网络流拆点建图,这个正好是缩点建图。吼吼吼~~~,建图的方式还是值得学习的。
因为星球数目最多十个,那么无论有多少个人,其不同选择也就2^10种咯。把不同的选择作为节点,节点就从10^5减少到了2^10,整整缩小了一个数量级呢。建立源点和汇点,源点和选择链接,边权为这种选择的出现次数;每种选择再与可到达的星球相连,边权为INF;星球与汇点相连,边权为星球的最大容量。然后跑最大流,判断是否满流即可。
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment (linker, "/STACK:1024000000,1024000000")
using namespace std; const int maxn = ;
const int INF = 0x3f3f3f3f; struct node
{
int to, next, w;
} edge[maxn**+];
int head[maxn+], Layer[maxn+], Hash[maxn+], tot; void Add (int from, int to, int w)
{
edge[tot].to = to;
edge[tot].w = w;
edge[tot].next = head[from];
head[from] = tot ++;
} int Scan ()
{
int res;
char ch;
res = ; while ((ch=getchar())<'' || ch>''); if (ch>='' && ch<='')
res = ch - ''; return res;
} bool CountLayer (int s, int e)
{
memset (Layer, , sizeof(Layer));
queue <int> Q;
Q.push (s);
Layer[s] = ;
while (!Q.empty())
{
int u = Q.front();
Q.pop();
for (int i=head[u]; i!=-; i=edge[i].next)
{
int v = edge[i].to;
if (edge[i].w && !Layer[v])
{
Layer[v] = Layer[u] + ;
Q.push (v);
if (v == e)
return true;
}
}
}
return false;
} int Dfs (int u, int e, int maxflow)
{
if (u == e)
return maxflow; int uflow = ;
for (int i=head[u]; i!=-; i=edge[i].next)
{
int v = edge[i].to;
if (!edge[i].w || Layer[v] != Layer[u]+)
continue; int flow = min (maxflow-uflow, edge[i].w);
flow = Dfs (v, e, flow);
uflow += flow;
edge[i].w -= flow;
edge[i^].w += flow;
if (maxflow == uflow)
break;
}
if (uflow == )
Layer[u] = ;
return uflow;
} int Dinic (int s, int e)
{
int maxflow = ;
while (CountLayer (s, e))
maxflow += Dfs (s, e, INF);
return maxflow;
} int main ()
{
int n, m, s, e, num;
while (scanf ("%d %d ", &n, &m) != EOF)
{
memset (head, -, sizeof(head));
memset (Hash, , sizeof(Hash));
tot = s = ;
e = (<<) + m + ;
for (int i=; i<=n; i++)
{
int y, x = ;
for (int j=; j<=m; j++)
{
int y = Scan();
x = x* + y;
}
Hash[x] ++;
} for (int i=; i<maxn; i++)
{
Add (s, i+, Hash[i]);
Add (i+, s, );
for (int j=; j<=m; j++)
if (i & <<(j-))
{
Add (i+, maxn+j, INF);
Add (maxn+j, i+, );
}
} for (int i=; i<=m; i++)
{
scanf ("%d", &num);
Add (maxn+i, e, num);
Add (e, maxn+i, );
} int ans = Dinic (s, e);
printf ("%s\n", ans == n ? "YES" : "NO");
}
return ;
}
Hdu 3605 Escape (最大流 + 缩点)的更多相关文章
- 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 3605 Escape(状压+最大流)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Sub ...
- hdu 3605 Escape 二分图的多重匹配(匈牙利算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others) ...
- HDU - 3605 Escape (缩点+最大流/二分图多重匹配)
题意:有N(1<=N<=1e5)个人要移民到M(1<=M<=10)个星球上,每个人有自己想去的星球,每个星球有最大承载人数.问这N个人能否移民成功. 分析:可以用最大流的思路求 ...
- HDU 3605 Escape(状态压缩+最大流)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所 ...
- HDU 3605 Escape(二分图多重匹配问题)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- [hdu 3605]Escape
这题的做法非常直观,却又非常不直观 先容许我吐一下槽吧~作者你的英语是读到火星上去了喵? 题目大体是说人类要移民,然后有 n 个人, m 个星球 每个人都有 m 个 0 . 1 数码表示他能否移民到该 ...
随机推荐
- 基于sentry的前端错误监控日志系统(部署sentry服务器/前端项目部署)-让前端最快的定位到生产问题
背景 在这越来越发达的网络时代,web应用也是越来越复杂,尤其是前端的开发,也是越来越受重视. 所以在我们前端开发完成后,会有一些列的web应用的上线验证,如自测.QA测试.code review 等 ...
- coco2dx新建项目报错,ld: -pie can only be used when targeting iOS 4.2 or later clang: error: linker command
在新建cocos2d-x以后,执行发现下面错误: ld: -pie can only be used when targeting iOS 4.2 or later clang: error: lin ...
- IEnumerator<TItem>和IEnumerator Java 抽象类和普通类、接口的区别——看完你就顿悟了
IEnumerable 其原型至少可以说有15年历史,或者更长,它是通过 IEnumerator 来定义的,而后者中使用装箱的 object 方式来定义,也就是弱类型的.弱类型不但会有性能问题,最主要 ...
- C++标准I/O库:iostream, fstream, sstringstream
在写代码的过程中.我们最常做的事就是io操作,不管是对控制台,还是文件.但一段时间不写代码就忘了,这里理一下C++标准I/O库的详细类和操作. C++的标准I/O库包含我们常常使用的iostream, ...
- 使用python生成c文件模板
目标 完成一个python脚本,实现指定名字后,自动生成.c和.h的模板.例如: /** * @file epc.c * @author 陈维 * @version V01 * @date 2017. ...
- visio2010对齐粘附功能
对齐与粘附功能在绘图时应用非常广泛.可以快速将图形对齐,以及将连接点准确地吸附在你想要连接的点上. 那么visio2010对齐粘附功能隐藏在什么地方呢? 你可以点击[视图]选项卡,在[视觉帮助]组中. ...
- is id() == 从内存的最小化占用角度解释 我是孕育者,我也应该这样设计 变,必然伴随着加法 一个list是否可以执行set()
def f(a, b): print(a is b, b is a, a == b, a.__eq__(b), id(a), id(b)) f(2, 2) f([2], [2]) f('2', '2' ...
- python3 安装 #zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz Modules/Setup.dist https://askubuntu ...
- 显示 目录 大小 du
[root@hadoop1 /]# du -BG -d 11G ./boot0G ./dev63G ./homedu: 无法访问"./proc/6689/task/6689/fd/4&qu ...
- java元组-泛型
需要组合对象的时候使用元组可以简化代码,不需要每当需要组合类的时候都去创建一个新的对象.单元素就是常见的泛型,可以两个三个到多个元素:元组可以继承:java泛型不能使用基本类型如int long 必须 ...