zoukankan      html  css  js  c++  java
  • hdu 1507 Uncle Tom's Inherited Land* (二分匹配)

    点击打开链接

    题目有指出 ( (N x M) - K <= 50), 所以最多也就 50 个点. 然后遍历图上

    每一个可行点点, 把它和他 上下左右的可行点连边, 最后就得到了一个二分图, 然后直接

    最大匹配, 不过结果有问题, 分析不透彻, 出现了重边. 再 分析下, 因为相邻块之间的下标

    和存在奇偶关系, 所以只取 偶数 或 奇数点 建图就行了.

    #include"stdio.h"
    #include"string.h"
    #define N 110
    struct node
    {
        int x,y;
    }aa[51];
    int hash[N][N],a[N][N];
    int map[N][N],v[N],mark[N];
    int n,m,cnt;
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,1,-1};
    void get_map()
    {
        int i,j,k,x,y;
        scanf("%d",&k);
        memset(hash,0,sizeof(hash));
        while(k--)
        {
            scanf("%d%d",&x,&y);
            hash[x][y]=1;
        }
        cnt=1;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
                if(hash[i][j]==0)
                {
                    a[i][j]=cnt;
                    aa[cnt].x=i;
                    aa[cnt].y=j;
                    cnt++;
                }
        }
        memset(map,0,sizeof(map));
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
                if(hash[i][j]==0)
                {
                    for(k=0;k<4;k++)
                    {
                        x=i+dx[k];
                        y=j+dy[k];
                        if(x>=1&&x<=n&&y>=1&&y<=m&&hash[x][y]==0)
                        {
                            map[a[i][j]][a[x][y]]=1;
                            map[a[x][y]][a[i][j]]=1;
                        }
                    }
                }
        }
    }
    int dfs(int k)
    {
        int i;
        for(i=1;i<cnt;i++)
        {
            if((aa[i].x+aa[i].y)%2==1)
                continue;
            if(map[k][i]&&!v[i])
            {
                v[i]=1;
                if(mark[i]==-1||dfs(mark[i]))
                {
                    mark[i]=k;
                    return 1;
                }
            }
        }
        return 0;
    }
    void output()
    {
        int i;
        for(i=1;i<cnt;i++)
            if(mark[i]!=-1)
            printf("(%d,%d)--(%d,%d)\n",aa[i].x,aa[i].y,aa[mark[i]].x,aa[mark[i]].y);
    }
    void solve()
    {
        int i,count;
        count=0;
        memset(mark,-1,sizeof(mark));
        for(i=1;i<cnt;i++)
        {
            if((aa[i].x+aa[i].y)%2==0)
                continue;
            memset(v,0,sizeof(v));
            if(dfs(i))
                count++;
        }
        printf("%d\n",count);
        output();
        printf("\n");
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=-1)
        {
            if(!n&&!m)
                break;
            get_map();
            solve();
        }
        return 0;
    }


  • 相关阅读:
    仿google的suggest
    renderjs主动发起通讯
    数据库设计原则(转载)
    SqlBulkCopy批量插入
    NPOI使用word模板
    visual studio 2010与NUNIT集成调试
    bond
    linux 内核参数优化
    Linux清除用户登陆及历史命令
    nginx 常用请求
  • 原文地址:https://www.cnblogs.com/yyf573462811/p/6365271.html
Copyright © 2011-2022 走看看