HDU - 3605 Escape(最大流+状态压缩)
2017-01-13 13:44
369 查看
点击查看原题
题目大意:
有n个人m个星球,每个人都有自己中意的星球(可以多个),每个星球有居住的人数上限。问是否可以每个人都去到自己中意的星球。
分析:
看起来是裸的最大流问题,也果断交了一发(TLE,人数过多),上网参考了一下大牛的状态压缩想法,因为星球最多只有10个所以可以把每个人的状态看成是2^m。然后统计同一种方案的人数作为容量。
建图:
源点链接被选用了的方案 容量为选择人数
方案链接位为1的星球 容量为inf
星球链接汇点 容量为限制人数
跑最大流看是否等于n
AC代码
题目大意:
有n个人m个星球,每个人都有自己中意的星球(可以多个),每个星球有居住的人数上限。问是否可以每个人都去到自己中意的星球。
分析:
看起来是裸的最大流问题,也果断交了一发(TLE,人数过多),上网参考了一下大牛的状态压缩想法,因为星球最多只有10个所以可以把每个人的状态看成是2^m。然后统计同一种方案的人数作为容量。
建图:
源点链接被选用了的方案 容量为选择人数
方案链接位为1的星球 容量为inf
星球链接汇点 容量为限制人数
跑最大流看是否等于n
AC代码
#include<stdio.h> #include<string.h> #include<vector> #include<set> #include<queue> #define inf 100000000 using namespace std; struct tree { int from,to,cap,flow; tree(){} tree(int ff,int tt,int cc,int ww) { from=ff;to=tt;cap=cc;flow=ww; } }; int n,m; vector<tree> G; vector<int> v[20000]; int cur[20000]; int que[2000000]; int d[20000]; int sink,source; void addtree(int ff,int tt,int cc) { G.push_back(tree(ff,tt,cc,0)); G.push_back(tree(tt,ff,0,0)); int m=G.size(); v[ff].push_back(m-2); v[tt].push_back(m-1); } bool bfs() { memset(d,-1,sizeof(d)); int front=0,back=0; que[back++]=source; d[source]=0; while(front<back) { int p=que[front++]; if(p==sink) return true; for(int i=0;i<v[p].size();i++) { tree &e=G[v[p][i]]; if(d[e.to]==-1&&e.flow<e.cap) { d[e.to]=d[p]+1; que[back++]=e.to; } } } return false; } int dfs(int x,int a) { if(x==sink||a==0) return a; int flow=0,f; for(int &i=cur[x];i<v[x].size();i++) { tree &e=G[v[x][i]]; if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; G[v[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0) break; } } if(!flow) d[x]=-2; return flow; } int maxflow() { int flow=0; //printf("!!!"); while(bfs()) { //printf("!!"); memset(cur,0,sizeof(cur)); flow+=dfs(source,inf); } return flow; } int peo[2000]; int main() { while(scanf("%d%d",&n,&m)==2) { memset(peo,0,sizeof(peo)); for(int i=0;i<20000;i++) v[i].clear(); G.clear(); source=1,sink=3000; for(int i=0;i<(1<<m);i++) { int t=i; for(int j=m-1;j>=0&&t;j--) { if(t&1) addtree(i+2,2000+j,inf); t>>=1; } } for(int i=0;i<n;i++) { int t=0; for(int j=0;j<m;j++) { int aa; scanf("%d",&aa); t<<=1; t+=aa; } peo[t]++; } for(int i=0;i<(1<<m);i++) { if(peo[i]) addtree(source,i+2,peo[i]); } //printf("!!!\n"); for(int i=0;i<m;i++) { int aa; scanf("%d",&aa); addtree(2000+i,sink,aa); } //printf("!!!"); if(n==maxflow()) printf("YES\n"); else printf("NO\n"); } }
相关文章推荐
- HDU 3605 Escape(最大流+状态压缩)
- hdu 3605 Escape (最大流+状态压缩)
- HDU 3605 Escape(最大流+状态压缩)
- HDU 3605 Escape(最大流+状态压缩)
- HDU 3605 —— Escape 状态压缩+最大流
- hdu 3605 Escape【图论-网络流-最大流-状态压缩】
- HDU 3605 Escape(状态压缩+最大流)
- HDU 3605 最大流+状态压缩
- HDU-3605 Escape(状态压缩+最大流求多重匹配、改版匈牙利算法)
- hdu 3605 Escape 状态压缩+最大流
- 【HDU - 3605 】Escape 【状态压缩 构图+最大流 or 多重匹配】
- hdu 3605 Escape【状态压缩+最大流Dinic+建图】
- HDU -- 3605 Escape(最大流 状态合并判满流)
- hdu3605 Escape(最大流+状态压缩)
- HDOJ 3605 - Escape 状态压缩缩点+最大流
- HDU 3605 Escape (网络流,最大流,位运算压缩)
- hdoj 3605 Escape 【状态压缩构图 + 最大流】
- hdoj--3605--Escape(状态压缩+最大流)
- hdu 3605_最大流 状态压缩
- HDU 3605 Escape 建图状态压缩