Hdu 3605 Escape (最大流 + 缩点)

题目链接:

  Hdu 3605  Escape

题目描述:

  有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功?

解题思路:

  正常情况下建图,不会爆内存,但是TLE还是稳稳的。以前只遇到过网络流拆点建图,这个正好是缩点建图。吼吼吼~~~,建图的方式还是值得学习的。

  因为星球数目最多十个,那么无论有多少个人,其不同选择也就2^10种咯。把不同的选择作为节点,节点就从10^5减少到了2^10,整整缩小了一个数量级呢。建立源点和汇点,源点和选择链接,边权为这种选择的出现次数;每种选择再与可到达的星球相连,边权为INF;星球与汇点相连,边权为星球的最大容量。然后跑最大流,判断是否满流即可。

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #pragma comment (linker, "/STACK:1024000000,1024000000")
  7 using namespace std;
  8
  9 const int maxn = 1024;
 10 const int INF = 0x3f3f3f3f;
 11
 12 struct node
 13 {
 14     int to, next, w;
 15 } edge[maxn*11*2+100];
 16 int head[maxn+100], Layer[maxn+100], Hash[maxn+100], tot;
 17
 18 void Add (int from, int to, int w)
 19 {
 20     edge[tot].to = to;
 21     edge[tot].w = w;
 22     edge[tot].next = head[from];
 23     head[from] = tot ++;
 24 }
 25
 26 int Scan ()
 27 {
 28     int res;
 29     char ch;
 30     res = 0;
 31
 32     while ((ch=getchar())<‘0‘ || ch>‘9‘);
 33
 34     if (ch>=‘0‘ && ch<=‘9‘)
 35         res = ch - ‘0‘;
 36
 37     return res;
 38 }
 39
 40 bool CountLayer (int s, int e)
 41 {
 42     memset (Layer, 0, sizeof(Layer));
 43     queue <int> Q;
 44     Q.push (s);
 45     Layer[s] = 1;
 46     while (!Q.empty())
 47     {
 48         int u = Q.front();
 49         Q.pop();
 50         for (int i=head[u]; i!=-1; i=edge[i].next)
 51         {
 52             int v = edge[i].to;
 53             if (edge[i].w && !Layer[v])
 54             {
 55                 Layer[v] = Layer[u] + 1;
 56                 Q.push (v);
 57                 if (v == e)
 58                     return true;
 59             }
 60         }
 61     }
 62     return false;
 63 }
 64
 65 int Dfs (int u, int e, int maxflow)
 66 {
 67     if (u == e)
 68         return maxflow;
 69
 70     int uflow = 0;
 71     for (int i=head[u]; i!=-1; i=edge[i].next)
 72     {
 73         int v = edge[i].to;
 74         if (!edge[i].w || Layer[v] != Layer[u]+1)
 75             continue;
 76
 77         int flow = min (maxflow-uflow, edge[i].w);
 78         flow = Dfs (v, e, flow);
 79         uflow += flow;
 80         edge[i].w -= flow;
 81         edge[i^1].w += flow;
 82         if (maxflow == uflow)
 83             break;
 84     }
 85     if (uflow == 0)
 86         Layer[u] = 0;
 87     return uflow;
 88 }
 89
 90 int Dinic (int s, int e)
 91 {
 92     int maxflow = 0;
 93     while (CountLayer (s, e))
 94         maxflow += Dfs (s, e, INF);
 95     return maxflow;
 96 }
 97
 98 int main ()
 99 {
100     int n, m, s, e, num;
101     while (scanf ("%d %d ", &n, &m) != EOF)
102     {
103         memset (head, -1, sizeof(head));
104         memset (Hash, 0, sizeof(Hash));
105         tot = s = 0;
106         e = (1<<10) + m + 1;
107         for (int i=1; i<=n; i++)
108         {
109             int y, x = 0;
110             for (int j=1; j<=m; j++)
111             {
112                 int y = Scan();
113                 x = x*2 + y;
114             }
115             Hash[x] ++;
116         }
117
118         for (int i=0; i<maxn; i++)
119         {
120             Add (s, i+1, Hash[i]);
121             Add (i+1, s, 0);
122             for (int j=1; j<=m; j++)
123                 if (i & 1<<(j-1))
124                 {
125                     Add (i+1, maxn+j, INF);
126                     Add (maxn+j, i+1, 0);
127                 }
128         }
129
130         for (int i=1; i<=m; i++)
131         {
132             scanf ("%d", &num);
133             Add (maxn+i, e, num);
134             Add (e, maxn+i, 0);
135         }
136
137         int ans = Dinic (s, e);
138         printf ("%s\n", ans == n ? "YES" : "NO");
139     }
140     return 0;
141 }
时间: 2024-10-28 20:24:03

Hdu 3605 Escape (最大流 + 缩点)的相关文章

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

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(状压+最大流)

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

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