hdoj 1281 棋盘游戏

求最大匹配的思路很直接。

求重要点的时候枚举每次删掉一条边,如果最大匹配不变,那就说明它不是关键点。

/*
 * Author: stormdpzh
 * HDOJ: 1281 棋盘游戏
 * Created Time: 2012/5/25 13:44:45
 */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <functional>

#define sz(v) ((int)(v).size())
#define rep(i, n) for(int i = 0; i < n; i++)
#define repf(i, a, b) for(int i = a; i <= b; i++)
#define repd(i, a, b) for(int i = a; i >= b; i--)
#define out(n) printf("%d\n", n)
#define mset(a, b) memset(a, b, sizeof(a))
#define wh(n) while(scanf("%d", &n) != EOF)
#define whz(n) while(scanf("%d", &n) != EOF && n != 0)
#define lint long long

using namespace std;

const int MaxN = 105;

struct Node {
    int x, y;
    
    Node(int _x, int _y) : x(_x), y(_y) {}
    
    bool operator < (const Node &t) const {
        return x < t.x || y < t.y;
    }
};
set<Node> st;
int n, m, k;
bool mp[MaxN][MaxN];
int x[MaxN], y[MaxN];
bool visited[MaxN];

void init()
{
    mset(mp, false);
    st.clear();
    rep(i, k) {
        int xx, yy;
        scanf("%d%d", &xx, &yy);
        st.insert(Node(xx, yy));
        mp[xx][yy] = true;
    }  
}

bool find(int u)
{
    repf(i, 1, m) {
        if(!visited[i] && mp[u][i]) {
            visited[i] = true;
            if(y[i] == -1 || find(y[i])) {
                y[i] = u;
                x[u] = i;
                return true;
            }
        }
    }
    return false;
}

int gao()
{
    int match = 0;
    mset(x, -1);
    mset(y, -1);
    repf(i, 1, n) {
        if(x[i] == -1) {
            mset(visited, false);
            if(find(i)) match++;
        }
    }
    return match;
}

int main()
{
    int ans = 1;
    while(scanf("%d%d%d", &n, &m, &k) != EOF) {
        init();
        int res = gao();
        int imp = 0;
        set<Node>::iterator it = st.begin();
        while(it != st.end()) {
            mp[it->x][it->y] = false;
            if(gao() < res) imp++;
            mp[it->x][it->y] = true;
            it++;
        }
        printf("Board %d have %d important blanks for %d chessmen.\n", ans++, imp, res);
    }
    return 0;
}


你可能感兴趣的:(hdoj 1281 棋盘游戏)