Oil Skimming HDU

来源:互联网 发布:外卖软件下载 编辑:程序博客网 时间:2024/06/14 18:01

点击打开链接

在一张地图中 一个点只可能与上下左右四个点存在关系 符合二分图性质 同时题目规定地图上两个‘#’即可凑成一对 用匈牙利算法解决即可

#include <bits/stdc++.h>using namespace std;vector <int> edge[360010];int mark[610][610];char mp[610][610];int clr[360010],match[360010],book[360010];int n,num;void build(int x,int y){    int next[4][2]={0,-1,-1,0,0,1,1,0};    int i,tx,ty,u,v;    u=mark[x][y];    for(i=0;i<4;i++)    {        tx=x+next[i][0];        ty=y+next[i][1];        if(tx<0||tx>n-1||ty<0||ty>n-1) continue;        if(mark[tx][ty]!=0)        {            v=mark[tx][ty];            edge[u].push_back(v);        }    }    return;}void paint(int u){    int i,v;    for(i=0;i<edge[u].size();i++)    {        v=edge[u][i];        if(clr[v]==0)        {            clr[v]=3-clr[u];            paint(v);        }    }    return;}int dfs(int u){    int i,v;    for(i=0;i<edge[u].size();i++)    {        v=edge[u][i];        if(book[v]==0)        {            book[v]=1;            if(match[v]==0||dfs(match[v]))            {                match[v]=u;                match[u]=v;                return 1;            }        }    }    return 0;}int main(){    int t,cas,i,j,ans;    scanf("%d",&t);    cas=1;    while(t--)    {        scanf("%d",&n);        for(i=0;i<n;i++)        {            scanf("%s",mp[i]);        }        memset(mark,0,sizeof(mark));        num=0;        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                if(mp[i][j]=='#')                {                    num++;                    mark[i][j]=num;                }            }        }        for(i=1;i<=num;i++)        {            edge[i].clear();        }        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                if(mp[i][j]=='#')                {                    build(i,j);                }            }        }        memset(clr,0,sizeof(clr));        for(i=1;i<=num;i++)        {            if(clr[i]==0)            {                clr[i]=1;                paint(i);            }        }        memset(match,0,sizeof(match));        ans=0;        for(i=1;i<=num;i++)        {            memset(book,0,sizeof(book));            if(clr[i]==2)            {                if(dfs(i)) ans++;            }        }        printf("Case %d: %d\n",cas++,ans);    }    return 0;}