HDU 3605 Escape 最大流
题意:
如果这是2012年世界末日怎么办?我不知道该怎么做。但是现在科学家们已经发现,有些星球上的人可以生存,但有些人却不适合居住。现在科学家们需要你的帮助,就是确定所有人都能在这些行星上生活。输入多组测试数据,每组数据的开头是n (1 <= n <= 100000), m (1 <= m <= 10) n表示地球上有n个人,m代表m星球,星球和人的标签都是从0开始的。这里有n行,每一行代表一个合适的居住条件的人,每一行有m个数字,第i个数字是1,表示一个人适合居住在第i个星球上,或者是0表示这个人不适合居住在第i个星球上。最后一行有m个数字,第i个数字ai表示第i个星球最能容纳ai人。0 <= ai <= 100000输出确定是否所有人都能达到这些标准如果可以输出YES,则输出NO。
代码:
1 //这道题一看见是一个最大流模板,但是这道题就是为了卡时间。。。
2 //因为题目上面n特别大,这个时候因为m只有10,此时最大也就只有2^10个选择,所以有好多人的选择是一样的
3 //那么我们要按照他们的选择来建图,这样的话边的数量就会大大减少
4 #include<stdio.h>
5 #include<string.h>
6 #include<iostream>
7 #include<algorithm>
8 #include<queue>
9 #include<math.h>
10 #include<stdlib.h>
11 #include<vector>
12 using namespace std;
13 const int maxn=200005;
14 const int INF=0x3f3f3f3f;
15 int head[maxn],cnt,st,en,dis[maxn],cur[maxn],v[maxn];
16 struct edge
17 {
18 int v,next,c,flow;
19 } e[1000005];
20 vector<int> state[maxn];
21 void add_edge(int x,int y,int z)
22 {
23 e[cnt].v=y;
24 e[cnt].c=z;
25 e[cnt].flow=0;
26 e[cnt].next=head[x];
27 head[x]=cnt++;
28
29 e[cnt].v=x;
30 e[cnt].c=z;
31 e[cnt].flow=0;
32 e[cnt].next=head[y];
33 head[y]=cnt++;
34 }
35 bool bfs()
36 {
37 memset(dis,0,sizeof(dis));
38 dis[st]=1;
39 queue<int>r;
40 r.push(st);
41 while(!r.empty())
42 {
43 int x=r.front();
44 r.pop();
45 for(int i=head[x]; i!=-1; i=e[i].next)
46 {
47 int v=e[i].v;
48 if(!dis[v] && e[i].c>e[i].flow)
49 {
50 dis[v]=dis[x]+1;
51 r.push(v);
52 }
53 }
54 }
55 return dis[en];
56 }
57 int dinic(int s,int limit)
58 {
59 if(s==en || !limit) return limit;
60 int ans=0;
61 for(int &i=cur[s]; i!=-1; i=e[i].next)
62 {
63 int v=e[i].v,feed;
64 if(dis[v]!=dis[s]+1) continue;
65 feed=dinic(v,min(limit,e[i].c-e[i].flow));
66 if(feed)
67 {
68 e[i].flow+=feed;
69 e[i^1].flow-=feed;
70 limit-=feed;
71 ans+=feed;
72 if(limit==0) break;
73 }
74 }
75 if(!ans) dis[s]=-1;
76 return ans;
77 }
78 int main()
79 {
80 int n,m;
81 char s[25][25];
82 int w[25][25];
83 while(~scanf("%d%d",&n,&m))
84 {
85 memset(head,-1,sizeof(head));
86 cnt=0;
87 int x;
88 st=0;
89 en=1024+2*m+1;
90 memset(v,0,sizeof(v));
91 // for(int i=1;i<=n;++i) //这种方法建图的时候它的终止点en要大于1024,这样的话跑的话太慢了
92 // { //所以这个时候en的大小要改变成n+m+1,这个时候就要用到n了,正确建图方式见下面
93 // int y=1,sum=0;
94 // for(int j=1;j<=m;++j)
95 // {
96 // scanf("%d",&x);
97 // if(x)
98 // {
99 // sum+=y;
100 // }
101 // y*=2;
102 // }
103 // v[sum]++;
104 // }
105 // if(v[0])
106 // {
107 // printf("NO\n");
108 // continue;
109 // }
110 // for(int i=1;i<=1024;++i)
111 // {
112 // if(v[i])
113 // {
114 // add_edge(st,i,v[i]);
115 // add_edge(i,st,0);
116 // }
117 // for(int j=0;j<m;++j)
118 // {
119 // if((1<<j)&i)
120 // {
121 // add_edge(i,1024+1+j,INF);
122 // add_edge(1024+1+j,i,0);
123 // }
124 // }
125 // }
126 // for(int i=1;i<=m;++i)
127 // {
128 // scanf("%d",&x);
129 // add_edge(1024+i,en,x);
130 // add_edge(en,1024+i,0);
131 // }
132 st=0,en=n+m+1;
133 int s,i,j,num; //因此用状态压缩进行缩点
134 for(i=0; i<=1024; i++)
135 state[i].clear();
136 for(i=1; i<=n; i++)
137 {
138 s=0;
139 for(j=0; j<m; j++)
140 {
141 scanf("%d",&num);
142 if(num==1)
143 s|=(1<<j); //C语言中的 |= 意思为:按位或后赋值
144 }
145 state[s].push_back(i);
146 } //缩点
147 int tmp,siz;
148 for(i=0; i<(1<<m); i++) //这点就比我原来的代码优化了
149 {
150 if(state[i].size()==0)
151 continue;
152 tmp=state[i][0];
153 siz=state[i].size();
154 add_edge(st,tmp,siz);
155 for(j=0; j<m; j++) //由原来容量为1改为缩点的个数
156 if(i&(1<<j))
157 add_edge(tmp,n+j+1,siz);
158 }
159 for(i=1; i<=m; i++)
160 {
161 scanf("%d",&num);
162 add_edge(i+n,en,num);
163 }
164
165 int ans=0;
166 while(bfs())
167 {
168 for(int i=0; i<=en; i++)
169 cur[i]=head[i];
170 ans+=dinic(st,INF);
171 }
172 if(ans==n)
173 {
174 printf("YES\n");
175 }
176 else printf("NO\n");
177 }
178 return 0;
179 }
HDU 3605 Escape 最大流的更多相关文章
- Hdu 3605 Escape (最大流 + 缩点)
题目链接: Hdu 3605 Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...
- HDU 3605 Escape 最大流+状压
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others) ...
- 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 Sub ...
- hdu 3605 Escape 二分图的多重匹配(匈牙利算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others) ...
- HDU 3605 Escape(状态压缩+最大流)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所 ...
- HDU - 3605 Escape (缩点+最大流/二分图多重匹配)
题意:有N(1<=N<=1e5)个人要移民到M(1<=M<=10)个星球上,每个人有自己想去的星球,每个星球有最大承载人数.问这N个人能否移民成功. 分析:可以用最大流的思路求 ...
- HDU 3605 Escape(二分图多重匹配问题)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- [hdu 3605]Escape
这题的做法非常直观,却又非常不直观 先容许我吐一下槽吧~作者你的英语是读到火星上去了喵? 题目大体是说人类要移民,然后有 n 个人, m 个星球 每个人都有 m 个 0 . 1 数码表示他能否移民到该 ...
随机推荐
- 系统吞吐量与QPS/TPS
QPS/TPS QPS:Queries Per Second意思是"每秒查询率",是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准. ...
- 【win10】win10下两个显示器不同桌面壁纸
win10系统下,双屏显示为不同的桌面壁纸 操作: 1.鼠标右键点击个性化 2.点击背景选项 3.在图片上右键选择要添加为背景的图片 同理,将另一个屏幕壁纸设为监视器1 最后效果为两个分屏为不同桌面壁 ...
- vue中computed/method/watch的区别
摘要:本文通过官方文档结合源码来分析computed/method/watch的区别. Tips:本文分析的源码版本是v2.6.11,文章中牵涉到vue响应式系统原理部分,如果不是很了解,建议先阅读上 ...
- 从定义到AST及其遍历方式,一文带你搞懂Antlr4
摘要:本文将首先介绍Antlr4 grammer的定义方式,如何通过Antlr4 grammer生成对应的AST,以及Antlr4 的两种AST遍历方式:Visitor方式和Listener方式. 1 ...
- Vue项目之实现登录功能的表单验证!
Vue项目之实现登录功能的表单验证! 步骤: 配置 Form表单验证; 1.必须给el-from组件绑定model 为表单数据对象 2 给需要验证的表单项 el-form-item 绑定 prop 属 ...
- linux通过ntpd同步服务器时间,
ntpd得rpm包下载地址:https://pkgs.org/download/ntp 比如我得服务器版本是centos7 x86的,那选择我点击的这一个: 下拉到最下面就有安装包下载了,我选择的是二 ...
- Property attribute.
class property(object): """ Property attribute. fget function to be used for getting ...
- trust an HTTPS connection 安全协议 随机数 运输层安全协议 应用层安全协议 安全证书
小结: 1.HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间) HTTPS(全称:Hyper Text Transfer Protocol over Secure ...
- BZOJ2120 数颜色(带修改的莫队算法)
Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜 ...
- 转载,Pandas 数据统计用法
pandas模块为我们提供了非常多的描述性统计分析的指标函数,如总和.均值.最小值.最大值等,我们来具体看看这些函数: 1.随机生成三组数据import numpy as npimport panda ...