[hdu 3605]Escape

这题的做法非常直观,却又非常不直观

先容许我吐一下槽吧~作者你的英语是读到火星上去了喵?

题目大体是说人类要移民,然后有 n 个人, m 个星球

每个人都有 m 个 0 、 1 数码表示他能否移民到该星球,每个星球有个最大人口容量

问是否有方案移民该 n 个人

乍一看很水,但是看看 n 的数据范围真是太感动人心了,有种这尼玛更本不是网络流的感脚——

但是 m 的范围只有 10 !直觉告诉我似乎可以动手脚的样子喵?

状压!因为不需要输出方案,所以两个可移民方案相同的人完全可以视为同一人

然后点就被压到了 1024 以内,妥妥地过掉了~

我才不会说我连边连错害我调了半小时呢喵

  1 #include <cstdio>
  2 #include <cstring>
  3 #define min(x, y) ((x)<(y) ? (x):(y))
  4 const int inf=0x7FFFFFFF;
  5 const int sizeOfPoint=10050;
  6 const int sizeOfEdge=500050;
  7
  8 int n, m, t;
  9 int S, T;
 10 int f[sizeOfPoint], a[sizeOfPoint];
 11
 12 struct edge {int point, flow; edge * next, * pair;};
 13 edge memory[sizeOfEdge], * port=memory;
 14 edge * e[sizeOfPoint];
 15 inline void clear() {port=memory; memset(e, 0, sizeof e); t=0; memset(f, 0, sizeof f);}
 16 inline edge * newedge(int point, int flow, edge * next) {edge * ret=port++; ret->point=point; ret->flow=flow; ret->next=next; ret->pair=NULL; return ret;}
 17 inline void build(int u, int v, int f) {e[u]=newedge(v, f, e[u]); e[v]=newedge(u, 0, e[v]); e[u]->pair=e[v]; e[v]->pair=e[u];}
 18 int h[sizeOfPoint];
 19 inline bool bfs();
 20 inline int aug();
 21 inline int dinic();
 22
 23 int main()
 24 {
 25     int x, state;
 26
 27     while (scanf("%d %d", &n, &m)!=EOF)
 28     {
 29         clear();
 30         for (int i=1;i<=n;i++)
 31         {
 32             state=0;
 33             for (int j=0;j<m;j++)
 34             {
 35                 scanf("%d", &x);
 36                 state|=x<<j;
 37             }
 38             if (!f[state]++) a[++t]=state;
 39         }
 40         S=0; T=t+m+1;
 41         for (int i=1;i<=t;i++)
 42         {
 43             build(S, i, f[a[i]]);
 44             for (int j=0;j<m;j++) if ((a[i]>>j)&1)
 45                 build(i, t+j+1, f[a[i]]);
 46         }
 47         for (int i=1;i<=m;i++)
 48         {
 49             scanf("%d", &x);
 50             build(t+i, T, x);
 51         }
 52
 53         if (dinic()==n) printf("YES\n");
 54         else printf("NO\n");
 55     }
 56
 57     return 0;
 58 }
 59 inline bool bfs()
 60 {
 61     static int q[sizeOfPoint];
 62     int l=0, r=0;
 63     memset(h, 0xFF, sizeof h); h[T]=0;
 64     for (q[r++]=T;l<r;l++)
 65     {
 66         int u=q[l];
 67         for (edge * i=e[u];i;i=i->next) if (i->pair->flow && h[i->point]==-1)
 68             h[q[r++]=i->point]=h[u]+1;
 69     }
 70     return h[S]>=0;
 71 }
 72 inline int aug()
 73 {
 74     static edge * t[sizeOfPoint], * path[sizeOfPoint];
 75     static int aug[sizeOfPoint];
 76     int flow=0;
 77
 78     memcpy(t, e, sizeof e);
 79     memset(path, 0, sizeof path);
 80     memset(aug, 0, sizeof aug);
 81     aug[S]=inf;
 82     for (int u=S; ; )
 83     {
 84         if (u==T)
 85         {
 86             flow+=aug[T];
 87             for (edge * i=path[T];i;i=path[i->point])
 88             {
 89                 i->pair->flow-=aug[T], i->flow+=aug[T];
 90                 aug[i->point]-=aug[T];
 91                 if (!aug[i->point]) h[i->point]=-1;
 92             }
 93             u=S;
 94         }
 95
 96         edge *& i=t[u];
 97         for ( ;i && (!i->flow || h[u]!=h[i->point]+1);i=i->next);
 98         if (i)
 99         {
100             path[i->point]=i->pair; aug[i->point]=min(aug[u], i->flow);
101             u=i->point; i=i->next;
102         }
103         else
104         {
105             if (u==S) break;
106             u=path[u]->point;
107         }
108     }
109
110     return flow;
111 }
112 inline int dinic()
113 {
114     int ret=0, flow;
115     while (bfs())
116         while (flow=aug())
117             ret+=flow;
118     return ret;
119 }

本傻调出翔系列

时间: 2024-11-10 07:56:36

[hdu 3605]Escape的相关文章

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

hdu 3605 Escape (二分图多重匹配)

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4298    Accepted Submission(s): 1129 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient

HDU 3605 Escape(最大流+缩点转换)

http://acm.hdu.edu.cn/showproblem.php?pid=3605 题目很简单,要求的就是最后能搬到星球上去的人的个数.刚开始看到,知道是最大流,就把人和星球都设为点,能生存就连线,权值为1,最后建立超级源点和超级汇点.求出最大流量即可.先是RE,开大数组后TLE.仔细算了,光光人到星球的便就可达到100w了,超时的概率太大了.后来找了解题报告,知道了缩点这一说,因为星球个数m最大只有10个,所以每个人最多只有1024种情况,把这每一种情况设为点(这里很抽象),将之与符

Hdu 3605 Escape (最大流 + 缩点)

题目链接: Hdu 3605  Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是TLE还是稳稳的.以前只遇到过网络流拆点建图,这个正好是缩点建图.吼吼吼~~~,建图的方式还是值得学习的. 因为星球数目最多十个,那么无论有多少个人,其不同选择也就2^10种咯.把不同的选择作为节点,节点就从10^5减少到了2^10,整整缩小了一个数量级呢.建立源点和汇点,源点和选择链接,边权为这种选

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 8001    Accepted Submission(s): 1758 Problem Description 2012 If this is the end of th

HDU 3605 Escape 最大流+状压

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7145    Accepted Submission(s): 1553 Problem Description 2012 If this is the end of the

HDU 3605 Escape(状压+最大流)

Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 9430    Accepted Submission(s): 2234 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient

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

http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意: 有n个人和m个星球,每个人可以去某些星球和不可以去某些星球,并且每个星球有最大居住人数,判断是否所有人都能去这m个星球之中. 思路: 这道题建图是关键,因为n的数量很大,如果直接将源点和人相连,是会超时的,因为m≤10,所以每个人的选择可以用二进制来存储,这样最多也就1<<m-1种状态,相同的就可以放在一起处理了. 1 #include<iostream> 2 #include&l

HDU 3605 Escape (最大流)

Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Description 2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do

HDU 3605 —— Escape 状态压缩+最大流

原题:http://acm.hdu.edu.cn/showproblem.php?pid=3605 #include<cstdio> #include<cstring> #include<string> #include<queue> #include<cmath> #include<vector> #include<algorithm> #define inf 1e9 using namespace std; const