Problem Description
Some 1×2 dominoes are placed on a plane. Each dominoe is placed either horizontally or vertically. It's guaranteed the dominoes in the same direction are not overlapped, but horizontal and vertical dominoes may overlap with each other. You task is to remove some dominoes, so that the remaining dominoes do not overlap with each other. Now, tell me the maximum number of dominoes left on the board.
Input
There are multiple input cases.
The first line of each case are 2 integers: n(1 <= n <= 1000), m(1 <= m <= 1000), indicating the number of horizontal and vertical dominoes.
Then n lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x + 1, y).
Then m lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x, y + 1).
Input ends with n = 0 and m = 0.
The first line of each case are 2 integers: n(1 <= n <= 1000), m(1 <= m <= 1000), indicating the number of horizontal and vertical dominoes.
Then n lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x + 1, y).
Then m lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x, y + 1).
Input ends with n = 0 and m = 0.
Output
For each test case, output the maximum number of remaining dominoes in a line.
Sample Input
2 3 0 0 0 3 0 1 1 1 1 3 4 5 0 1 0 2 3 1 2 2 0 0 1 0 2 0 4 1 3 2 0 0
Sample Output
4 6
Source
Recommend
分别把竖着的,横着的牌分成2分,把有重叠的牌连一条边,进行二分匹配,然后求最大独立集=顶点数-最大匹配数
分别把竖着的,横着的牌分成2分,把有重叠的牌连一条边,进行二分匹配,然后求最大独立集=顶点数-最大匹配数
#include<map>
#include<set>
#include<list>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<string>
#include<iostream>
#include<iterator>
#include<algorithm>
using namespace std;
const int maxn=1005;
struct node
{
int to;
int next;
}edge[maxn*maxn];
int head[maxn];
int tot;
int mark[maxn];
bool used[maxn];
int n,m;
struct List
{
int x1,y1;
int x2,y2;
}H_point[maxn],V_point[maxn];
void addedge(int from,int to)
{
edge[tot].to=to;
edge[tot].next=head[from];
head[from]=tot++;
}
bool is_overlapped(int a,int b)
{
if(H_point[a].x1==V_point[b].x1 && H_point[a].y1==V_point[b].y1)
return true;
else if(H_point[a].x1==V_point[b].x2 && H_point[a].y1==V_point[b].y2)
return true;
else if(H_point[a].x2==V_point[b].x1 && H_point[a].y2==V_point[b].y1)
return true;
else if(H_point[a].x2==V_point[b].x2 && H_point[a].y2==V_point[b].y2)
return true;
return false;
}
bool dfs(int x)
{
for(int i=head[x];i!=-1;i=edge[i].next)
{
if(!used[edge[i].to])
{
used[edge[i].to]=1;
if(mark[edge[i].to]==-1 || dfs(mark[edge[i].to]))
{
mark[edge[i].to]=x;
return true;
}
}
}
return false;
}
int hungary()
{
memset(mark,-1,sizeof(mark));
int ans=0;
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(dfs(i))
ans++;
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0 && m==0)
break;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&H_point[i].x1,&H_point[i].y1);
H_point[i].x2=H_point[i].x1+1;
H_point[i].y2=H_point[i].y1;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&V_point[i].x1,&V_point[i].y1);
V_point[i].x2=V_point[i].x1;
V_point[i].y2=V_point[i].y1+1;
}
memset(head,-1,sizeof(head));
tot=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(is_overlapped(i,j))
addedge(i,j);
}
printf("%d\n",m+n-hungary());
}
return 0;
}
本文介绍了一种解决二维平面上水平与垂直多米诺骨牌放置问题的方法,通过将水平和垂直骨牌视为二分图中的两个部分,并将相互重叠的骨牌间建立连接,进而利用匈牙利算法求解最大匹配数,最终得到可以不重叠放置的最大骨牌数量。
2770

被折叠的 条评论
为什么被折叠?



