Escape

题目:

非常裸的多重匹配。

可是点数较多,所以要用到状态压缩。

。。

。。

第一次写。

好厉害的赶脚。

#include <iostream>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std; const int INF = 1 << 30;
const int MAXN = 20000 + 10; //////////////////////////////
struct Edge{
int from,to,cap,flow;
Edge(){};
Edge(int _from,int _to,int _cap,int _flow)
:from(_from),to(_to),cap(_cap),flow(_flow){};
};
vector<Edge> edges;
vector<int> G[MAXN];
int d[MAXN],cur[MAXN];
int N,M,src,sink; //////////////////////////// int dp[MAXN]; void init(){
src = (1 << M) + M + 2; sink = src + 1;
for(int i = 0;i < sink + 2;++i)
G[i].clear();
edges.clear();
} void addEdge(int from,int to,int cap){
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0));
int sz = edges.size();
G[from].push_back(sz - 2);
G[to].push_back(sz - 1);
} void build(){
int x;
memset(dp,0,sizeof(dp)); for(int i = 0;i < N;++i){
int sum = 0;
for(int j = 0;j < M;++j){
scanf("%d",&x);
if(x) sum += (1 << j);
}
dp[sum]++; //第几个集合
} for(int i = 0;i < M;++i){
scanf("%d",&x);
addEdge((1 << M) + i,sink,x);
} for(int i = 0;i < (1 << M);++i)if(dp[i]){
addEdge(src,i,dp[i]);
for(int j = 0;j < M;++j){
if(i & (1 << j)){ //推断该星球是否属于该集合
addEdge(i,(1 << M) + j,dp[i]);
}
}
}
} bool BFS(){
fill(d,d+sink+2,-1);
queue<int> Q;
Q.push(src);
d[src] = 0; while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int i = 0;i < (int)G[x].size();++i){
Edge& e = edges[G[x][i]];
if(d[e.to] == -1&&e.cap > e.flow){
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return d[sink] > 0;
} int DFS(int x,int a){
if(x == sink||a == 0)
return a; int flow = 0,f;
for(int& i = cur[x];i < (int)G[x].size();++i){
Edge& e = edges[G[x][i]];
if(d[e.to] == d[x] + 1&&(f = DFS(e.to,min(a,e.cap - e.flow))) > 0){
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
} int maxFlow(){
int flow = 0;
while(BFS()){
memset(cur,0,sizeof(cur));
flow += DFS(src,INF);
}
return flow;
} int main(){
// freopen("Input.txt","r",stdin); while(scanf("%d%d",&N,&M) == 2){
init();
build(); int flow = maxFlow(); if(flow < N){
puts("NO");
} else {
puts("YES");
}
}
return 0;
}

试写了一个二分多重匹配,时间在该题上差点儿相同。第一次写这个多重匹配,凭着感觉写了一个。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std; const int MAXN = 100000 + 10;
int G[MAXN][15];
int match[15][MAXN],up[15],Link[15];
bool used[15];
int N,M; bool dfs(int u){
for(int v = 0;v < M;++v){
if(G[u][v] && !used[v]){
used[v] = 1;
if(Link[v] < up[v]){
match[v][Link[v]++] = u;
return true;
} else {
for(int i = 0;i < Link[v];++i){
if(dfs(match[v][i])){
match[v][i] = u;
return true;
}
}
}
}
} return false;
} void solve(){
int res = 0;
bool flag = false;
memset(match,-1,sizeof(match));
memset(Link,0,sizeof(Link)); for(int i = 0;i < N;++i){
memset(used,0,sizeof(used));
if(!dfs(i)){
res++;
flag = true; ///提前退出,反超时! !!!! !1
break;
}
}
if(flag){
puts("NO");
} else {
puts("YES");
}
}
int main()
{
// freopen("Input.txt","r",stdin); while(scanf("%d%d",&N,&M) == 2){
memset(G,0,sizeof(G));
for(int i = 0;i < N;++i){
for(int j = 0;j < M;++j){
scanf("%d",&G[i][j]);
}
} for(int i = 0;i < M;++i)
scanf("%d",&up[i]); solve();
}
return 0;
}

hdu Escape的更多相关文章

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

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

  2. HDU 3533 Escape(大逃亡)

    HDU 3533 Escape(大逃亡) /K (Java/Others)   Problem Description - 题目描述 The students of the HEU are maneu ...

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

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

  4. HDU 5389 Zero Escape(dp啊 多校)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5389 Problem Description Zero Escape, is a visual no ...

  5. HDU 3605 Escape 最大流+状压

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others)    ...

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

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

  7. hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    ...

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

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

  9. HDU 3533 Escape bfs 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=3533 一道普通的bfs,但是由于代码实现出了bug还是拖了很久甚至对拍了 需要注意的是: 1.人不能经过炮台 2 ...

随机推荐

  1. HMM XSS检测

    HMM XSS检测 转自:http://www.freebuf.com/articles/web/133909.html 前言 上篇我们介绍了HMM的基本原理以及常见的基于参数的异常检测实现,这次我们 ...

  2. matlab基本语法

    MATLAB基本语法 点乘运算 , 常与其他运算符 点乘运算,常与其他运算符联合使用(如.\) 矩阵生成 矩阵生成 向量生成或子阵提取本节将会介绍一些MATLAB的基本语法的使用. 持续更新... 在 ...

  3. 初涉springboot

    1.首先,我们需要了解微服务是什么? 微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用 ...

  4. Flask Cookie和Session

    1.1.概念 cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了解决这个问题,第 ...

  5. Struts2简单环境搭建

    一.开篇 Struts2是一个运行于web容器的表示层框架,其核心作用是帮助我们处理Http请求.Struts2处理Http请求(Request),并进行内部处理,再进行Http返回. 下载strut ...

  6. 多线程与MySQL(十)

    1.1 多线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合 ...

  7. log4j:WARN Please initialize the log4j system properly.解决方案

    在使用quarz任务调度框架时的错误,实际上这个问题很常见,并不影响程序的使用,只是缺少日志输出,完整错误信息: log4j:WARN No appenders could be found for ...

  8. css3新增的属性有哪些

    徐先森讲web CSS3新增的属性有哪些: CSS 用于控制网页的样式和布局. CSS3 是最新的 CSS 标准. CSS3新增了很多的属性,下面一起来分析一下新增的一些属性: 1.CSS3边框: b ...

  9. servletconfig和servletcontext学习

    servletconfig java.lang.String getInitParameter(java.lang.String name)  //根据参数名获取参数值 java.util.Enume ...

  10. 手写一个promise

    Promise A+ 规范:https://promisesaplus.com/ 注:以下代码没有通过 promises-aplus-tests 的全部测试,但基本功能还是全的( 测试结果: 864 ...