codevs 1022 覆蓋(匈牙利演算法)
阿新 • • 發佈:2018-11-06
codevs 1022 覆蓋(匈牙利演算法)
Time Limit: 1 Sec
Memory Limit: 128 MBDescription
有一個N×M的單位方格中,其中有些方格是水塘,其他方格是陸地。如果要用1×2的矩陣區覆蓋(覆蓋過程不容許有任何部分重疊)這個陸地,那麼最多可以覆蓋多少陸地面積。
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/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。