zoukankan      html  css  js  c++  java
  • UVALive 2635 匈牙利算法

    题意 给出k块地 规模n*m 需要在每块地中找至多一块h*w的地 这些地中如果包含字母 只能包含一种字母 如果一块地中选地使用了A 其余的地就不能使用A 但是全0可以重复

    问 最后能最多选出来多少块地

    因为每次选地的唯一 和 字母覆盖的唯一 可以很容易的想到二分图 

    暴力把每块地能够选地的类型找出来 形成关系矩阵 建图后 二分图的A区是选的地 B区是所有可以选的字母

    需要注意的是 既然全0的区域是可以多次选择的 那么 如果一块地可以选出全0的区域 就直接不管他 考虑二分图的时候 直接跳过

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<map>
    #include<iostream>
    #include<vector>
    using namespace std;
    int r,n,m,h,w;
    bool g[100][100];
    char s[500][500];
    bool vis[500];
    int linker[500];
    bool jiaru[500];
    bool fin(int u)
    {
        for(int i=1; i<30; i++)
        {
            if(g[u][i])
            {
                if(vis[i])
                {
                    vis[i]=false;
                    if(linker[i]==-1||fin(linker[i]))
                    {
                        linker[i]=u;
                        return true;
                    }
                }
            }
        }
        return false;
    }
    int xyl()
    {
        int tot=0;
        memset(linker,-1,sizeof(linker));
        for(int i=1; i<=r; i++)
        {
            if(jiaru[i])
                continue;
            memset(vis,true,sizeof(vis));
            if(fin(i))
                tot++;
        }
        return tot;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int ans=0;
            memset(g,false,sizeof(g));
            memset(jiaru,false,sizeof(jiaru));
            scanf("%d%d%d%d%d",&r,&n,&m,&h,&w);
            for(int i=1; i<=r; i++)
            {
                for(int k=1; k<=n; k++)
                    scanf("%s",s[k]+1);
                for(int k=1; k<=n-h+1; k++)
                {
                    if(jiaru[i])
                        break;
                    for(int j=1; j<=m-w+1; j++)
                    {
                        int many=0;
                        char f='0';
                        for(int l=k; l<=k+h-1; l++)
                        {
                            for(int o=j; o<=j+w-1; o++)
                            {
                                if(s[l][o]!='0')
                                {
                                    if(s[l][o]!=f)
                                    {
                                        many++;
                                        f=s[l][o];
                                    }
                                }
                            }
                        }
                        if(many==1)
                        {
                            int sz=(f-'A')+1;
                            g[i][sz]=true;
                        }
                        else if(many==0)
                        {
                            jiaru[i]=true;
                            ans++;
                            break;
                        }
                    }
                }
            }
            int res=xyl();
            printf("%d
    ",ans+res);
        }
    }
    

      

  • 相关阅读:
    web前端学习笔记(CSS盒子的定位)
    web前端学习笔记(CSS盒子的浮动)
    数百篇「原创」文章,助你完成技术「体系化」
    linux quota磁盘限额,引发的rename系统调用 errno:18
    dnsperf
    stop容器,把信号量传给java进程,优雅退出
    JNA 调用操作系统函数 和 系统调用
    自顶向下深入分析Netty(五)--Future
    来测试下你的Java编程能力
    Netty笔记
  • 原文地址:https://www.cnblogs.com/rayrayrainrain/p/5715635.html
Copyright © 2011-2022 走看看