HDU3605: Escape-二进制优化建图-最大流
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
目录
题意:传送门
原题目描述在最下面。
\(n(n\leq 100000)\)个人\(m(m\leq 10)\)个星球,每个星球容纳的人数有上限,每个人都有自己想去的星球意愿。问是否所有的都能去到外星球。
思路:
肯定不能暴力建图,因为人太多了。注意到m的大小只有10。刷过状压dp的人应该都能想到要二进制优化。
这是每个人其实都是没有区别的,有区别的只是他们的意愿。然后最多也只有\(2^{10} =1024\)种意愿。那就把这些当作\(1000\)多个点嘛。记录每种状态的人数。
- 超级源点S向每个星球连边,边容量为星球限值。
- 每个星球向对它有意愿的人点连边,流量为这些人的数量,这个我们之前预处理出来了。
- 然后\(2^m\)的状态点向超级汇点连边,流量为此状态的人数。
细节见代码。
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define mme(a,b) memset((a),(b),sizeof((a)))
#define fuck(x) cout<<"* "<<x<<"\n"
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MXN = 1e4+7;
const int MXE = 1e7+7;
struct DINIC{
int tot,vt,vs;
int d[MXN],head[MXN];
struct lp{
int to,w,nex;
}cw[MXE];
void add_edge(int a,int b,int c){
cw[++tot].to=b;cw[tot].nex=head[a],cw[tot].w=c;
head[a]=tot;
cw[++tot].to=a;cw[tot].nex=head[b],cw[tot].w=0;
head[b]=tot;
}
bool bfs(){
memset(d,-1,sizeof(d));
queue<int>Q;
Q.push(vt);d[vt]=0;
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(int i=head[u];i!=-1;i=cw[i].nex){
int v=cw[i].to;
if(cw[i^1].w&&d[v]==-1){
d[v]=d[u]+1;
Q.push(v);
}
}
}
return d[vs]!=-1;
}
int dfs(int x,int f){
if(x==vt||f==0) return f;
int use=0,w;
for(int i=head[x];i!=-1;i=cw[i].nex){
int to=cw[i].to;
if(d[to]==d[x]-1 && cw[i].w){
w=dfs(to,min(cw[i].w,f-use));
cw[i].w-=w,cw[i^1].w+=w;
use+=w;
if(use==f) return f;
}
}
return use;
}
void init(int st,int ed){
tot=-1;
memset(head,-1,sizeof(head));
vs=st;vt=ed;
}
int max_flow(){
int ans=0;
while(bfs())ans+=dfs(vs,INF);
return ans;
}
}dinic;
int n, m;
int vs, vt;
int num[1<<11];
int main(){
while(~scanf("%d%d",&n,&m)){
int state = 1<<m;
mme(num,0);
vs=state+m+1,vt=state+m+2;
dinic.init(vs,vt);
for(int i=1;i<=n;++i){
int tmp=0;
for(int j=1;j<=m;++j){
int x;scanf("%d",&x);
if(x)tmp|=(1<<(j-1));
}
num[tmp]++;
}
for(int i=1;i<=m;++i){
int x;scanf("%d",&x);
dinic.add_edge(vs,i+state,x);
}
for(int i=1;i<state;++i){
if(num[i]==0)continue;
dinic.add_edge(i,vt,num[i]);
for(int j=0;j<m;++j){
if(i&(1<<j)){
dinic.add_edge(state+j+1,i,num[i]);
}
}
}
LL ans = dinic.max_flow();
if(ans>=n)printf("YES\n");
else printf("NO\n");
}
return 0;
}
####原题目描述:
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
2010 ACM-ICPC Multi-University Training Contest(17)——Host by ZSTU
Recommend
lcy
HDU3605: Escape-二进制优化建图-最大流的更多相关文章
- 洛谷 P5331 - [SNOI2019]通信(CDQ 分治优化建图+费用流)
题面传送门 首先熟悉网络流的同学应该能一眼看出此题的建模方法: 将每个点拆成两个点 \(in_i,out_i\),连一条 \(S\to in_i\),容量为 \(1\) 费用为 \(0\) 的边 连一 ...
- 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流
[BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...
- 2018.09.27 codeforces1045A. Last chance(线段树优化建图+最大流)
传送门 看完题应该都知道是网络流了吧. 但是第二种武器直接建图会gg. 因此我们用线段树优化建图. 具体操作就是,对于这m个人先建一棵线段树,父亲向儿子连容量为inf的边,最后叶子结点向对应的人连容量 ...
- BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流
BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流 Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1 ...
- 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流
[BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...
- [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增
题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...
- [SDOI2017]天才黑客[最短路、前缀优化建图]
题意 一个 \(n\) 点 \(m\) 边的有向图,还有一棵 \(k\) 个节点的 trie ,每条边上有一个字符串,可以用 trie 的根到某个节点的路径来表示.每经过一条边,当前携带的字符串就会变 ...
- BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan
Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...
- 【LibreOJ】#6354. 「CodePlus 2018 4 月赛」最短路 异或优化建图+Dijkstra
[题目]#6354. 「CodePlus 2018 4 月赛」最短路 [题意]给定n个点,m条带权有向边,任意两个点i和j还可以花费(i xor j)*C到达(C是给定的常数),求A到B的最短距离.\ ...
随机推荐
- 帝国cms返回首页
<a href="[!--news.url--]">返回首页</a>
- luoguP2590 [ZJOI2008]树的统计 [树链剖分] [TLE的LCT]
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- Delphi 实现简易语音发音(基于TTS方式)
uses Comobj; procedure TForm1.Button1Click(Sender: TObject); var voice: OLEVariant; begin voice := C ...
- BZOJ 1303: [CQOI2009]中位数图(思路题)
传送门 解题思路 比较好想的思路题.首先肯定要把原序列转化一下,大于\(k\)的变成\(1\),小于\(k\)的变成\(-1\),然后求一个前缀和,还要用\(cnt[]\)记录一下前缀和每个数出现了几 ...
- python实现语音录入识别
一.介绍 1.第一步录音存入本地 2.调用百度语音识别sdk 注意点:百度语音识别对声音源有要求,比特率必须是256kbps 二.代码 #安装必要库 pip install baidu-aip #百度 ...
- NX二次开发-Block UI C++界面关于 在Block UI中UF_initialize();和UF_terminate();的使用
关于 在Block UI中UF_initialize();和UF_terminate();的使用 用Block UI作NX二次开发的时候,不需要在使用UFUN函数的时候加UF_initialize() ...
- int在64位操作系统中占多少位?
仍然是32位. 曾经是这样的:16位操作系统中,int 占16位:在32位操作系统中,int 占32位.但是现在人们已经习惯了 int 占32位,因此在64位操作系统中,int 仍为32位.64位整型 ...
- 项目管理模式:外瀑布内敏捷(有人称为“信封法”)--转自知乎大神:CORNERSTONE
作者:CORNERSTONE 链接:https://www.zhihu.com/question/265968122/answer/878124580 来源:知乎 著作权归作者所有.商业转载请联系作者 ...
- Mysql数据库命令行输入错误怎么办
Mysql数据库命令行输入错误 缺少另一半 错误输入 ' 或 " 时,必须键入另一半才能退出命令. 缺少分号 写入语句缺少分号需要补全. 输入quit或者exit退出 ctrl+c,完全退出 ...
- C# - 怎么截取字符串中指定字符及其后面的字符
方法1:去掉空格以及后面的字符 //怎么截取让date的值为"2011/12/9",即去掉空格以及后面的字符 string date = "2011/12/9 2 ...