题意:在一个N*M的矩形里,有K个hole 用1*2的木板去覆盖该矩形,每个木板只能覆盖相邻的两个格子,问是否能把每个格子都盖住。
思路:二分匹配。把图中能覆盖的格子从1 依次标号 若格子数为奇数 答案是NO 否则,把相邻的两个标号能连成一条边,求无向图的二分匹配数,当匹配数 == 格子数时,就能覆盖完。如下图
标号为:
1 0 2
3 4 5
6 7 0
8 9 10
比如说 4 这个点与 3 5 7 都有边相连。 这题得用边表做,起初用邻接矩阵 狂超时,改边表结构竟0Ms
//248K
0MS
#include <stdio.h>
#include <string.h>
#define Max 1050
#define M 35
int g[M][M],num,n,m,e;
int link[Max],yM[Max],head[Max];
bool vis[Max];
struct E
{
int to,nxt;
} edge[Max*8];
//每个点最多与其相邻4个点相连,且为无向图 故为8倍
void addedge(int cu,int cv)
{
edge[e].to = cv;
edge[e].nxt = head[cu];
head[cu] = e ++;
}
void Build (int x,int y)
//建图
{
if (x-1>0&&g[x-1][y] > 0)
{
addedge (g[x-1][y],g[x][y]);
addedge (g[x][y],g[x-1][y]);
}
if (x+1<=n&&g[x+1][y] > 0)
{
addedge (g[x+1][y],g[x][y]);
addedge (g[x][y],g[x+1][y]);
}
if (y-1 > 0&&g[x][y-1] > 0)
{
addedge (g[x][y-1],g[x][y]);
addedge (g[x][y],g[x][y-1]);
}
if (y +1 <= m&&g[x][y+1] > 0)
{
addedge (g[x][y+1],g[x][y]);
addedge (g[x][y],g[x][y+1]);
}
}
bool DFS (int u)
{
for (int i = head[u]; i != -1; i = edge[i].nxt)
{
int v = edge[i].to;
if (!vis[v])
{
vis[v] = true;
if (link[v] == -1||DFS(link[v]))
{
link[v] = u;
yM[u] = v;
return true;
}
}
}
return false;
}
int MaxMatch ()
//匈牙利算法 不用多说了吧
{
int u,res = 0;
memset(link,0xFF,sizeof(link));
memset (yM,0xFF,sizeof(yM));
for (u = 1; u <= num; u ++)
if(yM[u] == -1)
//加优化
{
memset (vis,false,sizeof(vis));
if (DFS(u))
res ++;
}
return
res;
}
int main ()
{
int k,x,y,i,j;
while (~scanf ("%d%d%d",&n,&m,&k))
{
memset (g,0,sizeof(g));
memset (head,0xFF,sizeof(head));
e = 0;
while (k --)
{
scanf ("%d%d",&y,&x);
g[x][y] = 1;
}
k = 0;
for (i = 1; i <= n; i ++)
for (j = 1; j <= m; j ++)
if (g[i][j] == 0)
g[i][j] = ++k;
else
g[i][j] = -1;
num = k;
if (k%2 == 1)
printf ("NO\n");
else
{
for (i = 1; i <= n; i ++)
for (j = 1; j <= m; j ++)
if (g[i][j] > 0)
Build(i,j);
if (k == MaxMatch())
printf ("%YES\n");
else
printf ("NO\n");
}
}
return 0;
}
思路:二分匹配。把图中能覆盖的格子从1 依次标号 若格子数为奇数 答案是NO 否则,把相邻的两个标号能连成一条边,求无向图的二分匹配数,当匹配数 == 格子数时,就能覆盖完。如下图
标号为:
1 0 2
3 4 5
6 7 0
8 9 10
比如说 4 这个点与 3 5 7 都有边相连。 这题得用边表做,起初用邻接矩阵 狂超时,改边表结构竟0Ms
//248K
#include <stdio.h>
#include <string.h>
#define Max 1050
#define M 35
int g[M][M],num,n,m,e;
int link[Max],yM[Max],head[Max];
bool vis[Max];
struct E
{
} edge[Max*8];
void addedge(int cu,int cv)
{
}
void Build (int x,int y)
{
}
bool DFS (int u)
{
}
int MaxMatch ()
{
}
int main ()
{
}