题意: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 /状态合并最大流的更多相关文章

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

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

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

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

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

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

  4. Tunnel Warfare HDU 1540 区间合并+最大最小值

    Tunnel Warfare HDU 1540 区间合并+最大最小值 题意 D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 题解思路 参考的大佬博客 这里 ...

  5. HDU 3605:Escape(最大流+状态压缩)

    http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,"Y" ...

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

    http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所 ...

  7. HDU 3605 最大流+状态压缩

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

  8. M - Escape - HDU 3605 - (缩点+最大流SAP)

    题目大意:2012世界末日来了,科学家发现了一些星球可以转移人口,不过有的人可以在一些星球上生存有的人不行,而且每个星球都有一定的承载量,现在想知道是否所有的人都可以安全转移呢? 输入:首先输入一个N ...

  9. HDU - 3605 Escape (缩点+最大流/二分图多重匹配)

    题意:有N(1<=N<=1e5)个人要移民到M(1<=M<=10)个星球上,每个人有自己想去的星球,每个星球有最大承载人数.问这N个人能否移民成功. 分析:可以用最大流的思路求 ...

随机推荐

  1. linux优化之优化开机自启动服务

    过滤出来需要的开机自启动项:chkconfig  --list|grep  3:on|grep  -v  "crond|sshd|network|rsyslog|sysstat" ...

  2. SQL语句小练习

    一.创建如下表结构(t_book) Id         主键   自增一 bookName   可变长 20 Price   小数 Author    可变长20 bookTypeId    图书类 ...

  3. Android CTS - Cannot run program "aapt"/ Fail to run aapt on .../apk installed but AaptParser failed

    今天同事碰到cts的一些问题,跑到某个apk的时候,就提示如下错误: Cannot run program "aapt": error=2. No such file or dir ...

  4. HDU 1561 The more, The Better(树形背包)

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  5. luogu3371 【模板】单源最短路径 dijkstra堆优化

    #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> ...

  6. J​a​y​r​o​c​k​.​J​s​o​n​读​取​j​s​o​n​数​据​(​n​e​t​)

    1 : 首 先 下 载 Jayrock.Json.dll 文 件 , 放 入 bin 目 录 中 : 地 址 : http://www.filediag.com/down/Jayrock.Json.d ...

  7. 基于UDP的交互的实例

    1.实现简单的客户端.服务端聊天交互 问题是:客户端不能单独一直发消息回复.. 服务端: import socket server=socket.socket(socket.AF_INET,socke ...

  8. ACM-ICPC 2018 沈阳赛区网络预赛 J树分块

    J. Ka Chang Given a rooted tree ( the root is node 11 ) of NN nodes. Initially, each node has zero p ...

  9. Good Bye 2017

    太菜了啊,一不小心就goodbye rating了 A. New Year and Counting Cards time limit per test 1 second memory limit p ...

  10. python风格之包导入

    导入总应该放在文件顶部, 位于模块注释和文档字符串之后, 模块全局变量和常量之前. 导入应该按照从最通用到最不通用的顺序分组: 标准库导入 第三方库导入 应用程序指定导入 每种分组中, 应该根据每个模 ...