HDU - 3605 Escape (缩点+最大流/二分图多重匹配)
题意:有N(1<=N<=1e5)个人要移民到M(1<=M<=10)个星球上,每个人有自己想去的星球,每个星球有最大承载人数。问这N个人能否移民成功。
分析:可以用最大流的思路求解该问题,新建源点和汇点,源点与人间加入弧,流量为他想去的星球之和;星球和汇点间加入弧,流量为其承载数量;人和星球间加入弧,流量无限。但是本题中N很大,M却很小,所以想去星球的编号组成的二进制数最多不超过1024,那么可以将N个人缩点。然后跑最大流,满流为N。
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int MAXN =1e4+,maxm =1e6+;
const int INF=0x3f3f3f3f; struct ISAP{
int head[MAXN], nv, n, tot; //nv:编号修改的上限
int num[MAXN], d[MAXN], pre[MAXN], cur[MAXN], q[MAXN];
struct node{
int v, next, cap;
}edge[maxm];
void init(){
memset(head,-,sizeof(head));
tot=;
}
void AddEdge(int u, int v, int cap){
edge[tot].v=v;edge[tot].cap=cap;edge[tot].next=head[u];
head[u]=tot++;
edge[tot].v=u;edge[tot].cap=;edge[tot].next=head[v];
head[v]=tot++;
}
void bfs(int s,int t){
memset(num,,sizeof(num));
memset(d,-,sizeof(d));
int f1=, f2=, i;
q[f1++]=t;
d[t]=;
num[]=;
while(f1>=f2){
int u=q[f2++];
for(i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(d[v]==-){
d[v]=d[u]+;
num[d[v]]++;
q[f1++]=v;
}
}
}
}
int isap(int s,int t){
memcpy(cur,head,sizeof(cur));
int flow=, i, u=pre[s]=s;
bfs(s,t);
while(d[s]<nv){
if(u==t){
int f=INF, pos;
for(i=s;i!=t;i=edge[cur[i]].v){
if(f>edge[cur[i]].cap){
f=edge[cur[i]].cap;
pos=i;
}
}
for(i=s;i!=t;i=edge[cur[i]].v){
edge[cur[i]].cap-=f;
edge[cur[i]^].cap+=f;
}
flow+=f;
if(flow>=n)
return flow;
u=pos;
}
for(i=cur[u];i!=-;i=edge[i].next)
if(d[edge[i].v]+==d[u]&&edge[i].cap) break;
if(i!=-){
cur[u]=i;
pre[edge[i].v]=u;
u=edge[i].v;
}
else{
if(--num[d[u]]==) break;
int mind=nv;
for(i=head[u];i!=-;i=edge[i].next){
if(mind>d[edge[i].v]&&edge[i].cap){
mind=d[edge[i].v];
cur[u]=i;
}
}
d[u]=mind+;
num[d[u]]++;
u=pre[u];
}
}
return flow;
}
}F; int vis[]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int S,T,N,M,u,v,tmp,k;
int op;
while(scanf("%d%d",&N,&M)==){
F.init();
k=;
memset(vis,,sizeof(vis));
for(int i=;i<=N;++i){
int x=;
for(int j=;j<=M;++j){
scanf("%d",&op);
x<<=;
x+=op; //转换为二进制状态
}
vis[x]++;
}
for(int i=;i<=;++i) if(vis[i]) k++; //记录缩点后点数
S=;T=k+M+; F.nv=k+M+,F.n = N;
int id=;
for(int i=;i<=;++i){
if(!vis[i]) continue;
id++;
int sta = i,cnt = vis[i];
for(int j=,t=;j<=sta;j<<=,t++){
if(j&sta) F.AddEdge(id,t+k,INF);
}
F.AddEdge(S,id,cnt);
}
for(int i=;i<=M;++i){
scanf("%d",&tmp);
F.AddEdge(i+k,T,tmp);
}
if(F.isap(S,T)==N) printf("YES\n");
else printf("NO\n");
}
return ;
}
还有一种做法是二分图多重匹配。二分图多重匹配的思路与匈牙利算法接近,也是从以匹配的点中寻找增广路。X部为N个人,Y部为M个星球,每个星球有自己的匹配上限。在时间上,两种实现方法所差不多。
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int maxn = 1e5+,maxm = 2e6+;
int N,M;
struct Node{
int K[];
}link[maxn];
int cnt[];
struct Edge{
int to,next;
}edges[maxm];
int head[maxn],tot;
bool used[];
int limit[]; void init()
{
tot=;
memset(head,-,sizeof(head));
} void AddEdge(int u,int v)
{
edges[tot].to = v;
edges[tot].next = head[u];
head[u] = tot++;
} bool dfs(int u){
int v;
for(int i=head[u];~i;i = edges[i].next){
v = edges[i].to;
if(!used[v]){
used[v]=true;
if(cnt[v]<limit[v]){
link[v].K[cnt[v]++]=u;
return true;
}
for(int j=;j<cnt[v];++j){
if(dfs(link[v].K[j])){
link[v].K[j]=u;
return true;
}
}
}
}
return false;
} bool hungary(){
memset(cnt,,sizeof(cnt));
for(int u=;u<=N;u++){
memset(used,,sizeof(used));
if(!dfs(u)) return false; //只要有一个人不能匹配则失败
}
return true;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T,u,v,tmp,k;
int op;
while(scanf("%d%d",&N,&M)==){
init();
for(int i=;i<=N;++i){
for(int j=;j<=M;++j){
scanf("%d",&op);
if(op) AddEdge(i,j);
}
}
for(int i=;i<=M;++i) scanf("%d",&limit[i]);
if(hungary()) printf("YES\n");
else printf("NO\n");
}
return ;
}
HDU - 3605 Escape (缩点+最大流/二分图多重匹配)的更多相关文章
- M - Escape - HDU 3605 - (缩点+最大流SAP)
题目大意:2012世界末日来了,科学家发现了一些星球可以转移人口,不过有的人可以在一些星球上生存有的人不行,而且每个星球都有一定的承载量,现在想知道是否所有的人都可以安全转移呢? 输入:首先输入一个N ...
- Hdu 3605 Escape (最大流 + 缩点)
题目链接: Hdu 3605 Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...
- 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 Subm ...
- hdu3605 Escape 二分图多重匹配/最大流
2012 If this is the end of the world how to do? I do not know how. But now scientists have found tha ...
- hdu 3605(二分图多重匹配)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- HDU3605 Escape —— 二分图多重匹配
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others) ...
- 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)
[题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个满足要求的组卷算法. ...
- 网络流24题 第五题 - PowerOJ1740 CodeVS1905 圆桌问题 二分图多重匹配 网络最大流
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - PowerOJ1740 - 有SPJ - 推荐 题目传送门 - CodeVS1905 - 无SPJ - 0% ...
随机推荐
- Oracle Tuning 总括
oracle tuning 分为3个阶段 1. application 调优阶段, 包括设计的调优, SQL语句调优, 管理权限等内容, (这部分是我的重点) (调优人员 application de ...
- 动态添加js的方法
var Skip={};//获取XMLHttpRequest对象(提供客户端同http服务器通讯的协议)Skip.getXmlHttpRequest=function (){ if ( window. ...
- java 搭建web项目
从git到maven都是莫名其妙的装上了.... 然后看了下报错,是数据的事,把链接字符串一改,数据库一建,ok,跑起来了 基本上没任何问题,唯一的问题就是我的网速太慢,maven了一夜的样子....
- Java中static的使用
static 使用之静态变量: 大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 static 大 ...
- mysql delimiter 存储过程
命令行登录mysql cd /d D:\database\mysql1\bin mysql.exe -P 3306 -h 127.0.0.1 -u root -p USE tbschedule del ...
- oralce 术语
§2.1 术语 l 数据库块(BLOCK) ORACLE 数据库中的最小存储和处理单位,包含块本身的头信息数据或PL/SQL代码. ORACLE 块的大小是可以在安装时选择“自定义安装”来指定,也可以 ...
- 一次Tomcat6.0.33版本号与6.0.44版本号差异所引发的问题
前序(公司应用为Web应用, 部署serverLinux + Nginx + Tomcat ) 一天收到公司报警邮件,显示个别机器方法调用严重超时,寻常都是在100ms以内响应的方法,突然某段时间响应 ...
- iOS捕获异常,常用的异常处理方法
本文转载至 http://www.cocoachina.com/ios/20141229/10787.html 前言:在开发APP时,我们通常都会需要捕获异常,防止应用程序突然的崩溃,防止给予用户不友 ...
- mongodb在32位机的连接
Windows 32bit版本安装Mongodb时,会发生的下面问题 2016-05-09T00:09:45.124+0800 I STORAGE [initandlisten] exception ...
- Linux下的Make与Makefile
原文转载自:http://www.cpplive.com/html/1776.html 另外一个不错的博客http://bbs.chinaunix.net/thread-1950588-1-1.htm ...