zoukankan      html  css  js  c++  java
  • 【codevs】1022覆盖(匈牙利算法)

    嗯,先上题目描述。。。

    此题接近裸的匈牙利算法,将陆地和其四周是陆地的点连一条边,这样就有了一个无向图。

    接着就是从第一个点出发枚举未被标记的点,标记与其对应的另一个点(因为是1*2的长方形)。

    开了一个四维数组e[x1][y1][x2][y2],若为零代表点(x1,y1)与(x2,y2)不连通。

    match[x1][y1][1]放与点(x1,y1)配对的另一个点的x,match[x1][y1][2]放与点(x1,y1)配对点的y。

    还有就是更改的时候记得双向更改,因为是无向图啊。

    然后就跑dfs,代码应该是可以看得懂的吧。。。

    #include<cstdio>
    #include<cstring>
    int m,n,k;
    int cc[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    int e[102][102][102][102]={0};
    bool ok[102][102],book[102][102];
    int match[102][102][3];
    bool dfs(int x,int y)
    {
        for(int i=0;i<4;i++)
        {
            int p1=x+cc[i][0];
            int p2=y+cc[i][1];
            if(p1>=1&&p1<=m&&p2>=1&&p2<=n)
            {
                if(!book[p1][p2]&&e[x][y][p1][p2])
                {
                    book[p1][p2]=1;
                    if(!match[p1][p2][1]||dfs(match[p1][p2][1],match[p1][p2][2]))
                    {
                        match[p1][p2][1]=x;
                        match[p1][p2][2]=y;
                        match[x][y][1]=p1;
                        match[x][y][2]=p2;
                        return true;
                    }
                }
            }
        }
        return false;
    }
    int main()
    {
        memset(ok,true,sizeof(ok));
        memset(match,0,sizeof(match));
        int sum=0;
        scanf("%d %d %d",&m,&n,&k);
        int l,r;
        for(int i=1;i<=k;i++)
        {
            scanf("%d %d",&l,&r);
            ok[l][r]=false;
        }
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(ok[i][j])
                {
                    if(i+1<=m&&ok[i+1][j])
                    {
                        e[i][j][i+1][j]=1;
                        e[i+1][j][i][j]=1;
                    }
                    if(j+1<=n&&ok[i][j+1])
                    {
                        e[i][j][i][j+1]=1;
                        e[i][j+1][i][j]=1;
                    }
                }
            }    
        }
            for(int i=1;i<=m;i++)
            {
                for(int j=1;j<=n;j++)
                {
                if(!ok[i][j])continue;
                memset(book,0,sizeof(book));
                if(!match[i][j][1]&&dfs(i,j))sum++;
                }
            }
        printf("%d",sum);
        return 0;
    }
    View Code
  • 相关阅读:
    百度云满速下载原理与方法
    新版知乎登录之post请求
    requests发送post请求的一些疑点
    Python3实现ICMP远控后门(下)之“Boss”出场
    Python3实现ICMP远控后门(中)之“嗅探”黑科技
    Python3实现ICMP远控后门(上)_补充篇
    Python3实现ICMP远控后门(上)
    反射-Class
    希尔排序(java)
    插入排序(java)
  • 原文地址:https://www.cnblogs.com/JKAI/p/6777309.html
Copyright © 2011-2022 走看看