这道题好多种做法,,,
1、联通图。
由于题目特点,这道题可以转化为求图的该图的各个子联通图,每个包含x个点的联通图都可以最多得到不重叠的x/2个牌。
注意这句话:很重要的(It's guaranteed the dominoes in the same direction are not overlapped, but horizontal and vertical dominoes may overlap with each other.)
代码如下:
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define M 2005
int n, m, u[M][2], v[M][2];
bool vis[150][150];
vector<int>g[150][150];
void dfs(int x, int y, int &tt)//遍历联通图得到节点数目
{
vis[x][y] = 1;
tt++;
for(int i = 0; i < (int)g[x][y].size(); i++)
{
int d = g[x][y][i];
int xx = u[d][0], yy = u[d][1];
if(vis[xx][yy]==0)
dfs(xx,yy,tt);
xx = v[d][0], yy = v[d][1];
if(vis[xx][yy]==0)
dfs(xx,yy,tt);
}
}
int main ()
{
int x, y;
while(scanf("%d %d",&n,&m), n+m)
{
for(int i = 0; i < 150; i++)
for(int j = 0; j < 150; j++)
g[i][j].clear();
for(int i = 0; i < n; i++)
{
scanf("%d %d",&x, &y);
u[i][0] = x;
u[i][1] = y;
v[i][0] = x+1;
v[i][1] = y;
g[x][y].push_back(i);
g[x+1][y].push_back(i);
}
for(int i = n; i < n+m; i++)
{
scanf("%d %d",&x, &y);
u[i][0] = x;
u[i][1] = y;
v[i][0] = x;
v[i][1] = y+1;
g[x][y].push_back(i);
g[x][y+1].push_back(i);
}
memset(vis,0,sizeof(vis));
int ans = 0, tt = 0;
for(int i = 0; i < 150; i++)
for(int j = 0; j < 150; j++)
if(g[i][j].size()!=0&&vis[i][j]==0)
{tt = 0; dfs(i,j,tt); ans+=(tt/2);}
printf("%d\n",ans);
}
return 0;
}