3140: [Hnoi2013]消毒

匈牙利匹配
观察题目发现肯定每次某一维选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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值