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. 例说Linux内核链表(三)

    经常使用的linux内核双向链表API介绍 linux link list结构图例如以下: 内核双向链表的在linux内核中的位置:/include/linux/list.h 使用双向链表的过程,主要 ...

  2. Oracle 11g 学习3——表空间操作

    一.表空间概述 表空间是Oracle中最大的逻辑存储结构,与操作系统中的数据文件相相应: 基本表空间:一般指用户使用的永久性表空间,用于存储用户的永久性数据          暂时表空间: 主要用于存 ...

  3. tomat遇到的一些错误

    资料链接:启动tomcat一闪而过的问题

  4. NESTED LOOPS & HASH JOIN & SORT MERGE JOIN

    表连接方式及使用场合 NESTED LOOP 对于被连接的数据子集较小的情况,nested loop连接是个较好的选择.nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个表里面查 ...

  5. android 打包工具

    sdk.jar-修改路径-JarToDex-DexToSmali-复制文件

  6. vue <router-view>没有渲染

    将routes中的components换成component

  7. linux 下vim中关于删除某段,某行,或者全部删除的命令

  8. 关于Android Studio更新后一直Refreshing的解决办法!

    今天更新了一下studio一直是这个问题 查了很多资料终于解决了 造成这个问题的原因是要更新的gradle版本和studio安装路径中的gradle版本不一致导致的 把他们改成一致的即可 在这个目录里 ...

  9. NGUI 使用Grid自动排列UI

    1,NGUI->Create Grid 2,把需要排列的UI放到Grid下边,对Grid进行参数设置

  10. 使用json_decode无法解析json

    在接入合作方接口时,遇到一个json无法解析出来代码如下: <?php $res='{"resultcode":007,"resMsg":"!& ...