1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
| #include <cstdio>
#include <cstring>
#include <algorithm>
struct Edge
{
int v;
Edge *next;
} g[10000], *header[5000], *head[5000];
int LinkSize, _link_size;
void AddEdge(Edge *&head, const int y)
{
Edge* const node = g+(LinkSize++);
node->v = y;
node->next = head;
head = node;
}
int T, a, b, c, ans, mat[5000], match[5000];
bool used[20], vis[5000];
inline int getid(const int x, const int y, const int z) { return x*b*c + y*c + z; }
bool find(const int u)
{
for (Edge *e = header[u]; e; e = e->next)
{
if (vis[e->v]) continue;
vis[e->v] = true;
if (match[e->v] == -1 || find(match[e->v]))
{
match[e->v] = u;
return true;
}
}
return false;
}
void dfs(const int step, int cnt)
{
if (cnt >= ans) return;
if (step == a)
{
LinkSize = _link_size;
memset(header, 0, sizeof(*header)*b);
for (int j = 0; j < b; ++j)
for (int k = 0; k < c; ++k)
{
bool flag = false;
for (Edge *e = head[j*c+k]; e && !flag; e = e->next)
flag = !used[e->v];
if (!flag) continue;
AddEdge(header[j], k);
}
memset(match, 0xFF, sizeof(*match)*c);
for (int i = 0; i < b; ++i)
{
memset(vis, 0, sizeof(*vis)*b);
if ((cnt += find(i)) >= ans) return;
}
ans = cnt;
return;
}
used[step] = true; dfs(step+1, cnt+1);
used[step] = false;dfs(step+1, cnt);
}
int solve()
{
scanf("%d%d%d", &a, &b, &c);
if (a <= b && a <= c)
for (int i = 0; i < a; ++i)
for (int j = 0; j < b; ++j)
for (int k = 0; k < c; ++k)
scanf("%d", mat+getid(i, j, k));
else if (b <= a && b <= c)
{
std::swap(a, b);
for (int j = 0; j < b; ++j)
for (int i = 0; i < a; ++i)
for (int k = 0; k < c; ++k)
scanf("%d", mat+getid(i, j, k));
}
else
{
std::swap(a, c);
for (int k = 0; k < c; ++k)
for (int j = 0; j < b; ++j)
for (int i = 0; i < a; ++i)
scanf("%d", mat+getid(i, j, k));
}
LinkSize = 0;
for (int j = 0; j < b; ++j)
for (int k = 0; k < c; ++k)
{
head[j*c+k] = 0;
for (int i = 0; i < a; ++i)
if (mat[getid(i, j, k)])
AddEdge(head[j*c+k], i);
}
_link_size = LinkSize;
ans = a;
dfs(0, 0);
return ans;
}
int main()
{
scanf("%d", &T);
while (T--)
printf("%d\n", solve());
}
|