您的位置:首页 > 其它

UVALive 5903 Piece it together 二分匹配,拆点 难度:1

2015-03-11 08:17 591 查看
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3914

对L研究可以发现

相当于黑-横白,黑-纵白,每个黑白都要被匹配到,其中黑的横纵各两次,

很自然的想到拆点,黑点拆成专门和横白连接的,专门和纵白连接的,

如果2*黑==白数,运行一次二分匹配算法,匹配数==白数则为可行,剩下的都不可行

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};
char maz[600][601];
int ind[600][600];
int n,m;
bool inmaz(int x,int y){return 0<=x&&x<n&&0<=y&&y<m;}
struct pnt{
int x,y;
pnt(){x=y=0;}
pnt(int x,int y){this->x=x;this->y=y;}
};
pnt pw[600*600],pb[600*600];
int lenw,lenb;
int e[2*600*600][8];
int len[2*600*600];

int mch[2*600*600];
bool used[2*600*600];

bool dfs(int s){
used[s]=true;
for(int i=0;i<len[s];i++){
int t=e[s][i];
if(mch[t]==-1||(!used[mch[t]]&&dfs(mch[t]))){
mch[t]=s;
mch[s]=t;
return true;
}
}
return false;
}

int match(){
memset(mch,-1,sizeof(int)*2*lenw);
int res=0;
for(int i=0;i<lenw*2;i++){
if(mch[i]==-1){
memset(used,false,2*lenw);
if(dfs(i)){
res++;
}
}
}
return res;
}

int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
lenb=lenw=0;
memset(len,0,sizeof(len));
memset(ind,0,sizeof(ind));
for(int i=0;i<n;i++)scanf("%s",maz[i]);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maz[i][j]=='W'){
ind[i][j]=lenw;
pw[lenw++]=pnt(i,j);
}
else if(maz[i][j]=='B'){
ind[i][j]=lenb;
pb[lenb++]=pnt(i,j);
}
}
}
if(lenw!=lenb*2){
puts("NO");
continue;
}
for(int i=0;i<lenb;i++){
int x=pb[i].x,y=pb[i].y;
for(int j=0;j<2;j++){
int txj=x+dx[j],tyj=y+dy[j];
if(!inmaz(txj,tyj)||maz[txj][tyj]!='W')continue;
int indj=ind[txj][tyj],hor=lenw+2*i+1;

e[indj][len[indj]++]=hor;
e[hor][len[hor]++]=indj;
}
for(int k=2;k<4;k++){
int txk=x+dx[k],tyk=y+dy[k];
if(!inmaz(txk,tyk)||maz[txk][tyk]!='W')continue;
int indk=ind[txk][tyk],gra=lenw+2*i;
e[indk][len[indk]++]=gra;
e[gra][len[gra]++]=indk;
}
}
int res=match();
if(res!=lenw)puts("NO");
else puts("YES");
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: