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

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;
}

  

时间: 2024-11-05 21:05:06

UVALive 5903 Piece it together 二分匹配,拆点 难度:1的相关文章

POJ 3020 Antenna Placement(二分匹配+拆点)

题目链接:http://poj.org/problem?id=3020 Description The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobile phone nets in Sweden. The most striking reason why they got the job, is their discovery of a new,

ZOJ 3646 Matrix Transformer 二分匹配,思路,经典 难度:2

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4836 因为要使对角线所有元素都是U,所以需要保证每行都有一个不同的列上有U,设(i,j)的位置是U, 以U为边,连接点i和点j+n,也即连接行点和列点,最大匹配为n则必定有解,否则必定无解 #include <cstdio> #include <iostream> #include <cstring> #include <cctype>

UVALive 6525 Attacking rooks 二分匹配 经典题

题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=4536">点击打开链接 题意: 给定n*n的棋盘, 能够在'.'上摆 象棋中的车(X是墙壁) 使得随意两个车都不能互相攻击到 问:最多能摆多少个车. 思路: 二分匹配 1.若没有X.那么做法就是 X点集为行,Y点集为列,对于图上的每一个点所在的行和列(x,y) 建一条边 x->y 2.有了X,那么对于每一个点所在的上方能接触到的X必须

kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选

Hdu 1045 二分匹配

题目链接 Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6282    Accepted Submission(s): 3551 Problem Description Suppose that we have a square city with straight streets. A map of a city i

HDU 1045 Fire Net (二分匹配)

Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Description Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street

ZOJ 1516 Uncle Tom&#39;s Inherited Land(二分匹配 最大匹配 匈牙利啊)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=516 Your old uncle Tom inherited a piece of land from his great-great-uncle. Originally, the property had been in the shape of a rectangle. A long time ago, however, his great-great-uncl

hdu 1498 50 years, 50 colors 二分匹配

50 years, 50 colors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1789    Accepted Submission(s): 978 Problem Description On Octorber 21st, HDU 50-year-celebration, 50-color balloons floating

HDU - 1045 Fire Net(二分匹配)

Description Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. A blockhouse is a small castle that has four openings through which to s