poj-2446

来源:互联网 发布:企汇网发布信息软件 编辑:程序博客网 时间:2024/06/07 03:06
// 1856K    797MS   G++#include <stdio.h>#include <string.h>#define MAX 35#define GRID_MAX MAX*MAXint G[MAX][MAX];char G_relation[GRID_MAX][GRID_MAX];int M; // lengthint N; // heightint K;int validGridNum;int V1[GRID_MAX];int V2[GRID_MAX];char waittingMove[GRID_MAX];char getPair(int curId) {    for (int i = 1; i <= validGridNum; i++) {        if (G_relation[curId][i]) { // if curId connect i            if (!V2[i]) {   // if i not assigned yet                V1[curId] = i;                V2[i] = curId;                return 1;            } else {                if (!waittingMove[V2[i]]) { // if i's owner do not waitting move                    waittingMove[V2[i]] = 1; // try to move, waiting                    if (getPair(V2[i])) {                        V1[curId] = i;                        V2[i] = curId;                        return 1;                    }                }            }        }    }    return 0;}void solve() {    validGridNum = N*M - K;    int gridId = 1;    for (int j = 0; j < N; j++) { // y        for (int i = 0; i < M; i++) { // x            if (G[i][j] != -1) {                G[i][j] = gridId++;                // printf("%d %d %d\n", i, j, G[i][j]);            }        }    }    // for (int j = 0; j < N; j++) {    //     for (int i = 0; i< M; i++) {    //         printf("%d ", G[i][j]);    //     }    //     printf("\n");    // }    for (int i = 0; i < M; i++) { //x         for (int j = 0; j < N; j++) { //y            int curId = G[i][j];            if (curId == -1) { // hole                continue;            }            //up            if (j < N-1) {                int upGridId = G[i][j+1];                if (upGridId != -1) { // upNode is not a hole                    G_relation[curId][upGridId] = 1;                    // printf("up %d %d\n", i, j);                }            }            //down            if (j > 0) {                int downGridId = G[i][j-1];                if (downGridId != -1) {                    G_relation[curId][downGridId] = 1;                    // printf("down %d %d\n", i, j);                }            }            //left            if (i > 0) {                int leftGridId = G[i-1][j];                if (leftGridId != -1) {                    G_relation[curId][leftGridId] = 1;                    // printf("left %d %d %d\n", i, j, G[i-1][j]);                }            }            //right            if (i < M-1) {                int rightGridId = G[i+1][j];                if (rightGridId != -1) {                    G_relation[curId][rightGridId] = 1;                    // printf("right %d %d %d\n", i, j, G[i+1][j]);                }            }        }    }    // for (int i = 1; i <= validGridNum; i++) {    //     for (int j = 1; j <= validGridNum; j++) {    //         printf("%d ", G_relation[i][j]);    //     }    //     printf("\n");    // }    int maxMatch = 0;    for (int i = 1; i <= validGridNum; i++) {        memset(waittingMove, 0, sizeof(waittingMove));        if (getPair(i)) {            maxMatch++;        }    }    // for (int i = 1; i <= validGridNum; i++) {    //     printf("%d %d\n", i, V1[i]);    // }    // printf("%d %d\n", maxMatch, validGridNum);    if (maxMatch == validGridNum) {        printf("YES\n");    } else {        printf("NO\n");    }}int main() {    while(scanf("%d %d %d", &N, &M, &K) != EOF) {        memset(G, 0, sizeof(G));        memset(V1, 0, sizeof(V1));        memset(V2, 0, sizeof(V2));        memset(G_relation, 0, sizeof(G_relation));        validGridNum = 0;        for (int i = 0; i < K; i++) {            int x;            int y;            scanf("%d %d", &x, &y);            G[x-1][y-1] = -1; // a hole is -1        }        solve();    }}

用的是点复制法来建的二分图,

每个点代表board上的一个不是hole的grid,依次从左到右,从下到上的编号,

然后,每个grid和其上下左右相邻的非hole的grid之间有连接的边,

在最后判断是否能够成功时有点迷糊, 直觉上直接用最大匹配数是否等于grid个数做的判断。

但是还不能清楚的解释原因,而觉得更严谨的应该是在这些最大匹配的边里面挨个检查边的端点,看是否有 grid数量/2的边(其实就是木板)的端点 将grid全部覆盖(这样就代表这题意 ,用木板在没有重叠的情况下将grid全部覆盖).


0 0
原创粉丝点击