
题解:
我们可以对棋盘进行黑白染色,使得任意相邻的两个格子颜色不相同,然后进行二分图最大匹配。
Code:
1 class Solution {
2 public:
3 int N;
4 int M;
5
6 vector<vector<int>> dir{{1,0},{0,1},{-1,0},{0,-1}};
7
8 int domino(int n, int m, vector<vector<int>>& broken) {
9 N=n;
10 M=m;
11 vector<vector<int>> grid(N*M,vector<int>(N*M,0));
12 vector<int> bro(N*M,0);
13 for(auto b:broken){
14 bro[b[0]*M+b[1]]=1;
15 }
16 for(int i=0;i<N*M;++i){
17 if(bro[i]) continue;
18 int x=i/M;
19 int y=i%M;
20 if((x+y)%2!=0) continue;
21 for(int d=0;d<4;++d){
22 int nx=x+dir[d][0];
23 int ny=y+dir[d][1];
24 if(nx<0 || nx>=N || ny<0 || ny>=M || bro[nx*M+ny]) continue;
25 grid[i][nx*M+ny]=1;
26 }
27 }
28 vector<int> mat(N*M,-1);
29 int res=0;
30 for(int i=0;i<N*M;++i){
31 if(bro[i]) continue;
32 int x=i/M;
33 int y=i%M;
34 if((x+y)%2==0){
35 vector<int> visited(N*M,0);
36 if(dfs(i,grid,visited, mat)){
37 res++;
38 }
39 }
40 }
41 return res;
42 }
43
44 bool dfs(int u, vector<vector<int>> &grid, vector<int> &visited, vector<int> &mat){
45 for(int i=0;i<M*N;++i){
46 if(grid[u][i]){
47 if(!visited[i]){
48 visited[i]=1;
49 if(mat[i]==-1 || dfs(mat[i],grid,visited,mat)){
50 mat[i]=u;
51 return true;
52 }
53 }
54 }
55 }
56 return false;
57 }
58 };
用最大流做:
1 class Solution {
2 public:
3 int N;
4 int M;
5 int S;
6 int T;
7 vector<vector<int>> dir{{1,0},{0,1},{-1,0},{0,-1}};
8
9 int domino(int n, int m, vector<vector<int>>& broken) {
10 N=n;
11 M=m;
12 S=M*N;
13 T=M*N+1;
14 vector<vector<int>> grid(N*M+3,vector<int>(N*M+3,0)); //残余容量
15 vector<int> bro(N*M,0);
16 for(auto b:broken){
17 bro[b[0]*M+b[1]]=1;
18 }
19 for(int i=0;i<N*M;++i){
20 if(bro[i]) continue;
21 int x=i/M;
22 int y=i%M;
23 if((x+y)%2!=0){
24 grid[i][T]=1;
25 continue;
26 }
27 grid[S][i]=1;
28 for(int d=0;d<4;++d){
29 int nx=x+dir[d][0];
30 int ny=y+dir[d][1];
31 if(nx<0 || nx>=N || ny<0 || ny>=M || bro[nx*M+ny]) continue;
32 grid[i][nx*M+ny]=1;
33 }
34 }
35 int res=0;
36
37 while(true){
38 vector<int> pre(N*M+3,-1);
39 bfs(grid,pre);
40
41 if(pre[T]==-1) break;
42 int minflow=INT_MAX;
43 int v=T;
44 while(true){
45 int u=pre[v];
46 minflow=min(minflow,grid[u][v]);
47 if(u==S) break;
48 v=u;
49 }
50 v=T;
51 while(true){
52 int u=pre[v];
53 grid[u][v]-=minflow;
54 grid[v][u]+=minflow;
55 if(u==S) break;
56 v=u;
57 }
58 res+=minflow;
59 }
60
61 return res;
62 }
63
64 void bfs(vector<vector<int>> &grid, vector<int> &pre){
65 queue<int> q;
66 vector<int> visited(N*M+3,0);
67 visited[S]=1;
68 q.push(S);
69 while(!q.empty()){
70 int cur=q.front();
71 q.pop();
72 if(cur==T) break;
73 for(int i=0;i<N*M+3;++i){
74 if(grid[cur][i]>0 && visited[i]==0){
75 visited[i]=1;
76 q.push(i);
77 pre[i]=cur;
78 }
79 }
80 }
81 }
82 };
来源:https://www.cnblogs.com/FEIIEF/p/12251087.html