生活随笔
收集整理的這篇文章主要介紹了
POJ2446【建图建图】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
給你一個n*n的矩陣,然后再給你幾個坑,然后問你能否被1*2的長方形給覆蓋;
- -弱知道了是二分匹配的做法,但是弱還是不會轉化,又是在建圖上GG了
分析:
從國際象棋的那個黑白色理解,這是一張二分圖(好像非常有道理)
建圖:由于是1*2的紙片覆蓋,那么這個區域的兩個點的(i+j)必然是一個奇數和一個偶數。
先搞好點,我們分別給奇數、偶數點 依次從1開始標號,相鄰的就是有一條邊;
這波建圖好是經典;
一般建圖弱感覺就是:先搞點,再建圖,有些還會再初始化一波;
然后就是求一下最大匹配,
如果最大匹配+K=N*M就輸出”YES”,否則就是”NO”
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<map>
#include<stack>
#include<algorithm>
using namespace std;
#define N 1500int ma[N][N];
int ls[N][N];
int n,m,t;
int cx[N];
int cy[N];
int ji,ou;
bool vis[N];
int findpath(
int u)
{
for(
int i=
1;i<ou;i++){
if(!vis[i]&&ma[u][i]){vis[i]=
1;
if(cy[i]==-
1||findpath(cy[i])){cx[u]=i;cy[i]=u;
return 1;}}}
return 0;
}
void solve()
{
memset(cx,-
1,
sizeof(cx));
memset(cy,-
1,
sizeof(cy));
int ans=
0;
for(
int i=
1;i<ji;i++){
memset(vis,
0,
sizeof(vis));ans+=findpath(i);}ans*
2==(m*n-t)?
printf(
"YES\n"):
printf(
"NO\n");
}
int main()
{
while(~
scanf(
"%d%d",&n,&m)){
scanf(
"%d",&t);
memset(ls,
0,
sizeof(ls));
for(
int i=
0;i<t;i++){
int x,y;
scanf(
"%d%d",&x,&y);ls[y][x]=-
1;}ji=ou=
1;
for(
int i=
1;i<=n;i++){
for(
int j=
1;j<=n;j++){
if(ls[i][j]!=-
1){
if((i+j)%
2==
0)ls[i][j]=ji++;
elsels[i][j]=ou++;}}}
memset(ma,
0,
sizeof(ma));
for(
int i=
1;i<=n;i++){
for(
int j=
1;j<=m;j++){
if(ls[i][j]!=-
1&&(i+j)%
2==
1){
if(ls[i-
1][j]>=
1)ma[ls[i-
1][j]][ls[i][j]]=
1;
if(ls[i+
1][j]>=
1)ma[ls[i+
1][j]][ls[i][j]]=
1;
if(ls[i][j-
1]>=
1)ma[ls[i][j-
1]][ls[i][j]]=
1;
if(ls[i][j+
1]>=
1)ma[ls[i][j+
1]][ls[i][j]]=
1;}}}solve();}
return 0;
}
[ls[i][j]]=
1;}}}solve();}
return 0;
}
轉載于:https://www.cnblogs.com/keyboarder-zsq/p/5934535.html
總結
以上是生活随笔為你收集整理的POJ2446【建图建图】的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。