sgu 190 分类: sgu 2015-04-25 13:03 31人阅读 评论(0) 收藏
首先可以观察出,每张骨牌可以覆盖相邻的两个方格,
即一张骨牌可以覆盖 两个横纵坐标之和的奇偶性不同的方格。
solution:首先根据横纵坐标之和的奇偶性对每个方格染色,然后根据骨牌放置方式连边,最后二分图匹配即可。
#include<map>
#include<queue>
#include<stack>
#include<utility>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<iostream>
#include<algorithm>
#define Px first
#define Py second
#define Mp(x,y) std::make_pair(x,y)
const int MAXN = 45, SIZE = MAXN*MAXN, Node = SIZE>>1;
struct Edge{int v,next;Edge(int v = 0,int next = 0):v(v),next(next){}};
int n , m;
bool map[MAXN][MAXN];
int nx = 0,ny = 0; bool flag;
int num[MAXN][MAXN] = {0};
std::pair<int,int>cx[Node],cy[Node];
int el = 0,head[Node] = {0};Edge edge[SIZE];
bool hash[Node];int link[Node] = {0};
int move[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
void NewEdge(int u,int v)
{++el, edge[el] = Edge(v,head[u]), head[u] = el;}
bool Find(int a)
{
for(int i = head[a]; i ; i = edge[i].next)
{
int p = edge[i].v;
if(hash[p]) continue;
hash[p] = true;
if(!link[p] || Find(link[p]))
{
link[p] = a;
return true;
}
}
return false;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("sgu190.in","r",stdin);
freopen("sgu190.out","w",stdout);
#endif
std::cin >> n >> m;
memset(map,true,sizeof(map));
for(int i = 1; i <= n; i++)
map[0][i] = map[n+1][i] = map[i][0] = map[n+1][i] = false;
for(int i = 1,a,b; i <= m; i++)
{
std::cin >> a >> b;
map[a][b] = false;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(map[i][j] == true)
if((i+j)&1) num[i][j] = ++ny, cy[ny] = Mp(i,j);
else num[i][j] = ++nx, cx[nx] = Mp(i,j);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(!((i+j)&1) && num[i][j])
for(int k = 0; k < 4; k++)
{
int ii = i+move[k][0], jj = j+move[k][1];
if(num[ii][jj]) NewEdge(num[i][j],num[ii][jj]);
}
flag = true;
if(nx != ny) flag = false;
for(int i = 1; i <= nx && flag; i++)
memset(hash,false,sizeof(hash)) ,flag = Find(i);
if(flag)
{
int cnt1 = 0, cnt2 = 0;
std::cout << "Yes" << std::endl;
for(int i = 1; i <= ny; i++)
{
std::pair<int,int>c1 = cx[link[i]],c2 = cy[i];
if(c1.Px == c2.Px) cnt1++;
if(c1.Py == c2.Py) cnt2++;
}
std::cout << cnt2 << std::endl;
for(int i = 1; i <= ny; i++)
{
std::pair<int,int>c1 = cx[link[i]],c2 = cy[i];
if(c1.Py == c2.Py)std::cout << std::min(c1.Px,c2.Px) << ' ' << c1.Py << std::endl;
}
std::cout << cnt1 << std::endl;
for(int i = 1; i <= ny; i++)
{
std::pair<int,int>c1 = cx[link[i]],c2 = cy[i];
if(c1.Px == c2.Px) std::cout << c1.Px << ' ' << std::min(c1.Py,c2.Py) << std::endl;
}
}
else
std::cout << "No" << std::endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。