zoj 1516 Uncle Tom's Inherited Land 最大独立边集合(最大匹配)

---恢复内容开始---

题意

  N*N的土地,某些点被挖成池塘了,其余为空地, 现在要组织成1*2的空地出售,问最大能出售的数量。

解题思路

  因为 R*C - K  <= 50  意味着,去除掉池塘后最多只有50个空地

  每个顶点与其上下左右的空地 连接,然后 构成二分图。  转换成求最大独立边(任意两条边不共用相同顶点)即为最大匹配。

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

const int N = 110;



int r, c, n, m, k;

bool g[N][N], use[N][N];

int ma[N], mb[N], num[N][N];

bool vis[N];

int dir[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };



int path( int u ){ 

    for(int v = 0; v < n; v++){ 

        if( g[u][v] && !vis[v] ){ 

            vis[v] = 1;

            if( ma[v] == -1 || path( ma[v] )){

                ma[v] = u; mb[u] = v;

                return 1;    

            }    

        }    

    }    

    return 0;

}

int main(){

    while( scanf("%d%d",&r,&c ) , r+c ){

        memset( use, 0, sizeof(use));

        memset( g, 0, sizeof(g));

        scanf("%d", &k);

        int a, b;

        for(int i = 0; i < k; i++){

            scanf("%d%d", &a,&b);

            use[a][b] = 1;

        }

        n = 0;

        for(int i = 1; i <= r; i++)

            for(int j = 1; j <= c; j++){

                if( !use[i][j] ){ 

                    num[i][j] = n++;

                }    

            }

        for(int i = 1; i <= r; i++)

            for(int j = 1; j <= c; j++){

                if( !use[i][j] ){

                    for(int d = 0; d < 4; d++){

                        int x = i+dir[d][0], y = j+dir[d][1];

                        if(  (x>=1)&&(x<=r)&&(y>=1)&&(y<=c) && !use[x][y] ){

                            g[ num[i][j] ][ num[x][y] ]= 1;

                            g[ num[x][y] ][ num[i][j] ] = 1;    

                        }    

                    }    

                }    

            } 

        memset( ma, 0xff, sizeof(ma));

        memset( mb, 0xff, sizeof(mb));

        int res = 0;

        for(int i = 0; i < n; i++){

            if( mb[i] == -1 ){ 

                memset( vis, 0, sizeof(vis));

                res += path( i );

            }    

        }

        printf("%d\n", res/2 );

    }

    return 0;    

}

 

---恢复内容结束---

你可能感兴趣的:(Inherit)