zoukankan      html  css  js  c++  java
  • bzoj4950: [Wf2017]Mission Improbable

    跟着靖靖做题%%%%%

    这题一看就觉得和之前的某场模拟赛的一道题很像,找假如某行某列的最大值一样的就可以只堆一个,跑匈牙利就行

    一开始以为箱子不能移动-_-!

    然后有个坑,大家都知道当这个位置有箱子就偷剩一个,但是假如当前行当前列没有箱子,就算他们最大值一样也不能建边

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    
    #define pd(a,b,c,d) a==b?c:d
    using namespace std;
    typedef long long LL;
    
    int n,m;LL c[110][110];
    LL hmx[110],lmx[110];
    void get_max()
    {
        for(int i=1;i<=n;i++)
        {
            hmx[i]=0;
            for(int j=1;j<=m;j++)
                hmx[i]=max(hmx[i],c[i][j]);
        }
        for(int j=1;j<=m;j++)
        {
            lmx[j]=0;
            for(int i=1;i<=n;i++)
                lmx[j]=max(lmx[j],c[i][j]);
        }
    }
    
    //----------init-------------
    
    struct node
    {
        int x,y,next;
    }a[11000];int len,last[110];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    void composition()//二分图匹配旨在解决某点同时作为hmx和lmx情况 
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(hmx[i]==lmx[j]&&c[i][j]!=0)ins(i,j);
    }
    int tim,v[110];
    int match[110];
    bool findmuniu(int x)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(v[y]!=tim)
            {
                v[y]=tim;
                if(match[y]==0||findmuniu(match[y])==true)
                {
                    match[y]=x;
                    return true;
                }
            }
        }
        return false;
    }
    
    //----------match-------------
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%lld",&c[i][j]);
        get_max();
        LL ans=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                ans+=pd(c[i][j],0,0,c[i][j]-1);
        for(int i=1;i<=n;i++)ans-=pd(hmx[i],0,0,hmx[i]-1);
        for(int j=1;j<=m;j++)ans-=pd(lmx[j],0,0,lmx[j]-1);
        
        composition();
        memset(match,0,sizeof(match));
        memset(v,0,sizeof(v));tim=0;
        for(int i=1;i<=n;i++)
        {
            tim++;
            if(findmuniu(i)==true)ans+=pd(hmx[i],0,0,hmx[i]-1);
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    C# 修改DataTable列 类型 并从新赋值
    buildroot 使用小记
    如何查看linux内核的版本号?
    在ubuntu上使用华为的3G无线上网卡
    在ubuntu上编译rasbian kernel(for raspberry pi 1)
    装了ubuntu后笔记本电脑的无线网卡用不了,怎么设置?
    Ubuntu下哪个PDF阅读器更好使???
    转载 :Linux有问必答:如何在Debian或Ubuntu上安装完整的内核源码
    Raspberry Pi
    cygwin下调用make出现的奇怪现象
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8795355.html
Copyright © 2011-2022 走看看