Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 10746 | Accepted: 3340 |
Description
We call a grid, which doesn’t contain a hole, a normal grid. Bob has to follow the rules below:
1. Any normal grid should be covered with exactly one card.
2. One card should cover exactly 2 normal adjacent grids.
Some examples are given in the figures below:
A VALID solution.
An invalid solution, because the hole of red color is covered with a card.
An invalid solution, because there exists a grid, which is not covered.
Your task is to help Bob to decide whether or not the chessboard can be covered according to the rules above.
Input
Output
Sample Input
4 3 2 2 1 3 3
Sample Output
YES
Hint
A possible solution for the sample input.
Source
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX 1050
struct edge
{
int v;
int next;
}E[5000];
int head[MAX];
int pre[MAX];
bool used[MAX];
bool map[35][35];
int n;
int m;
int num;
void init()
{
memset(head,-1,sizeof(head));
memset(pre,-1,sizeof(pre));
memset(map,0,sizeof(map));
num=0;
}
void add(int s,int t)
{
E[num].v=t;
E[num].next=head[s];
head[s]=num++;
}
bool dfs(int cur)
{
int i;
for(i=head[cur];i!=-1;i=E[i].next)
{
int v=E[i].v;
if(!used[v])
{
used[v]=1;
if(pre[v]==-1||dfs(pre[v]))
{
pre[v]=cur;
return true;
}
}
}
return false;
}
int hungary()
{
int i;
int res=0;
for(i=1;i<=n*m;i++)
{
memset(used,0,sizeof(used));
if(dfs(i))
res++;
}
return res;
}
int main()
{
int k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
init();
int i,j;
int x,y;
for(i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
map[y][x]=1;
}
if((n*m-k)%2)
{
printf("NO\n");
continue;
}
int id1,id2;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(!map[i][j])
{
id1=(i-1)*m+j;
if(j>1&&!map[i][j-1])
{
id2=id1-1;
add(id1,id2);
}
if(j<m&&!map[i][j+1])
{
id2=id1+1;
add(id1,id2);
}
if(i>1&&!map[i-1][j])
{
id2=id1-m;
add(id1,id2);
}
if(i<n&&!map[i+1][j])
{
id2=id1+m;
add(id1,id2);
}
}
}
}
int res=hungary()/2;
//cout<<"res="<<res<<endl;
if(res!=(n*m-k)/2)
{
printf("NO\n");
}
else
printf("YES\n");
}
}
//16MS
MYCode:
#include<iostream>
#include<cstring>
#include<cstdio>
const int MAXN=1050;
int uN,vN; //u,v数目
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
bool map[35][35];
int n,m;
bool dfs(int u)
{
int v;
for(v=1;v<=vN;v++)
if(g[u][v]&&!used[v])
{
used[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
return false;
}
int hungary()
{
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for(u=1;u<=uN;u++)
{
memset(used,0,sizeof(used));
if(dfs(u)) res++;
}
return res;
}
int main()
{
int k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
//init();
//memset(linker,-1,sizeof(linker));
memset(g,0,sizeof(g));
int i,j;
int x,y;
for(i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
map[y][x]=1;
}
if((n*m-k)%2)
{
printf("NO\n");
continue;
}
int id1,id2;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(!map[i][j])
{
id1=(i-1)*m+j;
if(j>1&&!map[i][j-1])
{
id2=id1-1;
//add(id1,id2);
g[id1][id2]=1;
}
if(j<m&&!map[i][j+1])
{
id2=id1+1;
//add(id1,id2);
g[id1][id2]=1;
}
if(i>1&&!map[i-1][j])
{
id2=id1-m;
//add(id1,id2);
g[id1][id2]=1;
}
if(i<n&&!map[i+1][j])
{
id2=id1+m;
//add(id1,id2);
g[id1][id2]=1;
}
}
}
}
uN=vN=m*n;
int res=hungary()/2;
//cout<<"res="<<res<<endl;
if(res!=(n*m-k)/2)
{
printf("NO\n");
}
else
printf("YES\n");
}
}
//1032MS
都是二分匹配,思路相同,邻接表16MS,邻接矩阵1032MS,可见邻接矩阵在处理稀疏图方面是不行的.