hdu 3605 /状态合并最大流
题意:N个人去m个星球,给出n个人可以去哪些星球的01矩阵。求是否能满足所有人都去。(n到10万,m<=10)
一看,起先一瞬间就建图,准备秒了,人向星球连边,直接最大流判断是否为n,提交超时。。。是啊,10W*10=100W条边,铁定超时。。
后来经牛提示:注意,m<10! 人的可以去星球,一共最多有10个,那只有 2^10次种情况,就是说x部与Y部连线情况很多点是一样的(所给的01矩阵,最多10W行,10列,必然有很多行是一样的)。所以X部只留1024个点,这些点中,点i含j个人的状态,者源点向其连边j,该点向可以去的连边,流量inf.
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=2000,maxe=200000;
int nume=0;int head[maxv];int e[maxe][3];
void inline adde(int i,int j,int c)
{
e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
e[nume++][2]=c;
e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
e[nume++][2]=0;
}
int ss,tt,n,m;
int vis[maxv];int lev[maxv];
bool bfs()
{
for(int i=0;i<tt+1;i++)
vis[i]=lev[i]=0;
queue<int>q;
q.push(ss);
vis[ss]=1;
while(!q.empty())
{
int cur=q.front();
q.pop();
for(int i=head[cur];i!=-1;i=e[i][1])
{
int v=e[i][0];
if(!vis[v]&&e[i][2]>0)
{
lev[v]=lev[cur]+1;
vis[v]=1;
q.push(v);
}
}
}
return vis[tt];
}
int dfs(int u,int minf)
{
if(u==tt||minf==0)return minf;
int sumf=0,f;
for(int i=head[u];i!=-1&&minf;i=e[i][1])
{
int v=e[i][0];
if(lev[v]==lev[u]+1&&e[i][2]>0)
{
f=dfs(v,minf<e[i][2]?minf:e[i][2]);
e[i][2]-=f;e[i^1][2]+=f;
sumf+=f;minf-=f;
}
}
if(!sumf) lev[u]=-1;
return sumf;
}
int dinic()
{
int sum=0;
while(bfs())sum+=dfs(ss,inf);
return sum;
}
int contain[15];int mark[1025];
void read_build()
{
int tx;
for(int i=0;i<n;i++)
{
int tkind=0;
for(int j=0;j<m;j++)
{
scanf("%d",&tx);
if(tx==1)
tkind=tkind|(tx<<(m-j-1)); //二进制压缩状态,或者开10维数组判重也方便。
}
mark[tkind]++;
}
for(int i=0;i<=1024;i++)
{
if(mark[i]!=0)
adde(ss,i,mark[i]);
}
for(int i=0;i<=1024;i++)
{
if(mark[i]!=0)
{
int ti=i;int cwei=0;
while(ti!=0)
{
if(ti%2==1)
adde(i,m-1-cwei+1024,inf);
ti=ti/2;
cwei++;
}
}
}
for(int i=0;i<m;i++) //每个星球人数
{
scanf("%d",&contain[i]);
}
for(int i=0;i<m;i++) //星球
{
adde(i+1024,tt,contain[i]);
}
/* for(int i=0;i<=n*m+1;i++)
for(int j=head[i];j!=-1;j=e[j][1])
{
printf("%d->%d:%d\n",i,e[j][0],e[j][2]);
}*/
}
void init()
{
nume=0; ss=1050;tt=ss+1;
for(int i=0;i<=tt;i++)
{
head[i]=-1;
contain[i]=mark[i]=0;
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
read_build();
int ans=dinic();
if(ans==n)printf("YES\n");
else printf("NO\n");
}
return 0;
}
hdu 3605 /状态合并最大流的更多相关文章
- HDU 3605 Escape(状压+最大流)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Sub ...
- 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 (最大流 + 缩点)
题目链接: Hdu 3605 Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...
- Tunnel Warfare HDU 1540 区间合并+最大最小值
Tunnel Warfare HDU 1540 区间合并+最大最小值 题意 D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 题解思路 参考的大佬博客 这里 ...
- HDU 3605:Escape(最大流+状态压缩)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,"Y" ...
- HDU 3605 Escape(状态压缩+最大流)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所 ...
- HDU 3605 最大流+状态压缩
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- M - Escape - HDU 3605 - (缩点+最大流SAP)
题目大意:2012世界末日来了,科学家发现了一些星球可以转移人口,不过有的人可以在一些星球上生存有的人不行,而且每个星球都有一定的承载量,现在想知道是否所有的人都可以安全转移呢? 输入:首先输入一个N ...
- HDU - 3605 Escape (缩点+最大流/二分图多重匹配)
题意:有N(1<=N<=1e5)个人要移民到M(1<=M<=10)个星球上,每个人有自己想去的星球,每个星球有最大承载人数.问这N个人能否移民成功. 分析:可以用最大流的思路求 ...
随机推荐
- mysql关联查询
mysql数据库的统计------生成统计信息 1.distinct:在一组之中将各个唯一的值找出来,如找出所有的品牌种类 mysql>select distinct brand_kind fr ...
- Unity基础-脚本的优化
脚本的优化 object pool 避免频繁的内存分配和gc噩梦(字符串相加?) 是否有必要都写在update里?分帧? 需要的只取一次 使用editor内赋值,而不是find 复杂的物理 复杂的数学 ...
- leetcode-20-Dynamic Programming
303. Range Sum Query - Immutable 解题思路: Note里说sumRange会被调用很多次..所以简直强烈暗示要做cache啊...所以刚开始,虽然用每次都去遍历数组求和 ...
- 原来针对新唐mcu,keil有免费许可
MDK for Nuvoton Cortex-M0/M23:The MDK for Nuvoton Cortex-M0/M23 is a license paid by Nuvoton. It is ...
- 关于host,nslookup,dig 的安装
host,nslookup,dig依赖bind包,所以先看一下系统有没有bind包 命令如下:rpm -qa |grep bind 如果没有或者版本太低请升级安装 命令是:yum install bi ...
- ROM,PROM,EPROM,EEPROM及FLASH存储器的区别
在微机的发展初期,BIOS都存放在ROM(Read Only Memory,只读存储器)中.ROM内部的资料是在ROM的制造工序中,在工厂里用特殊的方法被烧录进去的,其中的内容只能读不能改,一旦烧录进 ...
- 使用像AdminLTE的前端框架,树形导航菜单实现方式都有哪些?
之前用easyui等富前端框架开发的时候都是使用封装好的县城的插件,现在使用最新的类似AdminLTE似的前段框架实现树形菜单都用什么方式? 后台拼接html然后前端用JS append方法添加还是直 ...
- HDU 4812 D Tree 树分治
题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...
- CodeForces 599E Sandy and Nuts 状压DP
题意: 有一棵\(n(1 \leq n \leq 13)\)个节点的树,节点的标号为\(1 \sim n\),它的根节点是\(1\). 现在已知它的\(m(0 \leq m < n)\)条边,和 ...
- Zipkin和微服务链路跟踪
https://cloud.tencent.com/developer/article/1082821 Zipkin和微服务链路跟踪 本期分享的内容是有关zipkin和分布式跟踪的内容. 首先,我们还 ...