1. 程式人生 > >hdu1281(棋盤遊戲,車的放置)

hdu1281(棋盤遊戲,車的放置)

memset ring ostream ges pos syn 坐標 stdin mes

Problem Description

給定一個n * m的棋盤,在棋盤裏放盡量多的國際象棋中的車,使他們不能相互攻擊 已知有些格子不能放置,問最多能放置多少個車 並計算出必須棋盤上的必須點。

Input

第一行有三個數N、M、K(1<N,M<=100 1<K<=N*M),表示了棋盤的高、寬,以及可以放“車”的格子數目。接下來的K行描述了所有格子的信息:每行兩個數X和Y,表示了這個格子在棋盤中的位置。

output

對輸入的每組數據,按照如下格式輸出:
Board T have C important blanks for L chessmen.

思路:對於第一個問題 可以把行、列看做二分圖的左右節點,共n + m個節點 對所有可放置車的坐標(x, y) 把x,y連邊 然後放一個車相當於將x, y兩節點匹配 然後就可以用二分圖最大匹配來做了

對於第二個問題,暴力枚舉所有(x,y),並將其挖掉,如果匹配數減少了,(x,y)就是必須點。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 11000;
int n, m, q, mat[220];
bool vis[220], f[220][220];

int head[220],now;
struct edges{
    int to,next;
}edge[N<<2];
void add(int u,int v){ edge[++now] = {v,head[u]}; head[u] = now;}

struct input{
    int x,y;
}inp[N];
void init(){
    memset(edge,0,sizeof(edge));
    memset(head,0,sizeof(head)); now = 0;
    memset(mat,0,sizeof(mat));
}

bool dfs(int x){
    for(int i = head[x]; i; i = edge[i].next){
        int v = edge[i].to;
        if(!vis[v] && !f[x][v]){
            vis[v] = 1;
            if(!mat[v] || dfs(mat[v])){
                mat[v] = x;
                return 1;
            }
        }
    }
    return 0;
}

int main(){
//    freopen("data.in","r",stdin);
    ios::sync_with_stdio(false);
    int kase = 0;
    while(cin>>n>>m>>q){
        init();
        int x,y;
        for(int i = 1; i <= q; i++){
            cin>>x>>y; y += n;
            inp[i] = {x, y};
            add(x,y);// add(y,x);
        }
        int ans = 0;
        for(int i = 1; i <= n; i++){
            memset(vis,0,sizeof(vis));
            if(dfs(i)) ans++;
        }
        int tot = 0;
        for(int i = 1; i <= q; i++){
            f[inp[i].x][inp[i].y] = f[inp[i].y][inp[i].x] = 1;  //枚舉每個可放置的點 
            memset(mat,0,sizeof(mat));
            int cnt = 0;                                      //cnt記錄每次挖去一個點後的匹配數 
            for(int j = 1; j <= n; j++){
                memset(vis,0,sizeof(vis));
                if(dfs(j)) cnt++;
            }
            if(cnt < ans) tot++;
            f[inp[i].x][inp[i].y] = 0;
        }
        printf("Board %d have %d important blanks for %d chessmen.\n",++kase,tot,ans);
    }
    return 0;
}

  

hdu1281(棋盤遊戲,車的放置)