1. 程式人生 > >codevs 1022 覆蓋(匈牙利演算法)

codevs 1022 覆蓋(匈牙利演算法)


codevs 1022 覆蓋(匈牙利演算法)

  Time Limit: 1 Sec
  Memory Limit: 128 MB

Description

   有一個N×M的單位方格中,其中有些方格是水塘,其他方格是陸地。如果要用1×2的矩陣區覆蓋(覆蓋過程不容許有任何部分重疊)這個陸地,那麼最多可以覆蓋多少陸地面積。
p1
 

Input

   輸入檔案的第一行是兩個整數N,M (1<=N,M<=100),第二行為一個整數K( K<=50),接下來的K行,每行兩個整數X,Y表示K個水塘的行列位置。(1<=X<=N,1<=Y<=M)。
 

Output

   輸出所覆蓋的最大面積塊(1×2面積算一塊)。

Sample Input

   4 4
  6
  1 1
  1 4
  2 2
  4 1
  4 2
  4 4
  

Sample Output

  4

HINT

題目地址:codevs 1022 覆蓋

題目大意: 題目很簡潔了:)

題解:

  棋盤黑白染色一下
  黑色塊白色塊二分圖匹配
  每個黑塊都只能和上下左右四個白塊匹配
  匈牙利跑一邊就好了
  極限 \(O(N^4)\) 然而顯然跑不到


AC程式碼

#include <cstdio>
#include <cstring> 
using namespace std;
const int N=105;
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};
int n,m,K,Ans;
bool mark[N][N],used[N][N];
struct note{
    int x,y;
}res[N][N]; 
bool find(int x,int y){
    for(int i=0;i<4;i++){
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(1<=nx && nx<=n && 1<=ny && ny<=m && !mark[nx][ny]){
            if(!used[nx][ny]){
                used[nx][ny]=1;
                if(!res[nx][ny].x || find(res[nx][ny].x,res[nx][ny].y)){
                    res[nx][ny]=(note){x,y};
                    return 1;
                }
            }
        }
    }
    return 0;
}
int main(){
    scanf("%d%d",&n,&m);
    scanf("%d",&K);
    while(K--){
        int x,y;
        scanf("%d%d",&x,&y);
        mark[x][y]=1;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(!mark[i][j] && (i&1)==(j&1)){
                memset(used,0,sizeof(used));
                if(find(i,j))
                    Ans++;
            }
    printf("%d\n",Ans);
    return 0;
}


  作者:skl_win
  出處:https://www.cnblogs.com/shaokele/
  本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。