匈牙利匹配
观察题目发现肯定每次某一维选1,然后另两维就可以覆盖完,
所以暴力枚举某一维,然后考虑另两维如何最小。
显然是个匈牙利匹配的裸题。
注意这道题一定要加贪心优化,不然稳t。
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x; i <= y; ++i)
using namespace std;
const int N = 5e3+50;
int a[4],p[4],Link[N],e,cnt,ans;
int tot,head[N],to[N],nxt[N],w[N];
int vis[N],now,z;
bool q[N];
int x[5] = {0,2,1,1};
int y[5] = {0,3,3,2};
inline void add(int x,int y,int val) { nxt[tot] = head[x]; to[tot] = y; w[tot] = val; head[x] = tot++; }
bool dfs(int x)
{
for(register int i = head[x];~i;i = nxt[i])
if(vis[to[i]] != now && !q[w[i]])
{
vis[to[i]] = now;
if(!Link[to[i]] || dfs(Link[to[i]]))
{
Link[to[i]] = x;
return true;
}
}
return false;
}
int mx;
inline void find(int z)
{
rep(i,1,mx) Link[i] = 0,vis[i] = 0;
int aans = z;now = 0;
rep(i,1,mx)
{
++now;
if(dfs(i)) ++aans;
if(aans >= ans) return;
}
ans = aans;
}
void Dfs(int x)
{
if(x == a[e] + 1) return void(find(z));
Dfs(x + 1); q[x] = 1;++z; Dfs(x + 1);--z;q[x] = 0;
}
inline void solve()
{
memset(head,-1,sizeof head);tot = 0;
ans = N;cnt = 0;
rep(i,1,3) scanf("%d",&a[i]);
e = a[1] > a[2] ? 2 : 1; e = a[e] > a[3] ? 3 : e;
mx = max(a[x[e]],a[y[e]]);
int op;
rep(i,1,a[1]) rep(j,1,a[2]) rep(k,1,a[3])
{
scanf("%d",&op);
if(!op) continue;
p[1] = i;p[2] = j;p[3] = k;
add(p[x[e]],p[y[e]],p[e]);
}
Dfs(1);
printf("%d\n",ans);
}
int main()
{
freopen("1.in","r",stdin);
int t;
scanf("%d",&t);
while(t --) solve();
return 0;
}