/*
哎哟~~英文水平不好理解不了题意,在网上看的题意。
给你一个矩阵 由.和#组成,#代表10*10油,点代表水,现在用一个20*10的勺子从海里把油弄上来,
不能将海水和油一起弄上来,问你最多能挖多少勺油上来。
思路:是每两个连在一起的#号一勺油,可以将他们连一条边,然后一共有多少条边,就是多少勺油。
二分图的最大匹配~~~就是顶点与顶点一一对应匹配,这里也是,两个#一一匹配。求最大能匹配多少,
就是求二分图的最大匹配。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<queue>
using namespace std;
int n;
struct node
{
int x,y;
};
char map[601][601];
int map1[601][601];
vector<int>G[360001];
int cnt;
int match[360001];
int vis3[360001];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int jude(int x,int y)
{
if(x<1||x>n||y<1||y>n) return 0;
return 1;
}
int find(int x)
{
for(int i=0;i<G[x].size();i++)
{
int v=G[x][i];
if(!vis3[v])
{
vis3[v]=1;
if(match[v]==-1||find(match[v]))
{
match[v]=x;
return 1;
}
}
}
return 0;
}
int solove()
{
int ans=0;
memset(match,-1,sizeof(match));
for(int i=1;i<cnt;i++)
{ memset(vis3,0,sizeof(vis3));
if(find(i)) ans++;
}
return ans/2;
}
int main()
{
int t;
scanf("%d",&t);
int sss=1;
while(t--)
{
scanf("%d",&n);
cnt=1;;
memset(map1,0,sizeof(map1));
for(int i=0;i<360001;i++)
{
G[i].clear();
}
for(int i=1;i<=n;i++)
{
scanf("%s",map[i]+1);
for(int j=1;j<=n;j++)
{
if(map[i][j]=='#')
{
map1[i][j]=cnt++;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(map[i][j]=='#')
{
for(int k=0;k<4;k++)
{
int xx=i+dir[k][0];
int yy=j+dir[k][1];
if(map[xx][yy]=='#')
{
G[map1[i][j]].push_back(map1[xx][yy]);
}
}
}
}
}
int anx=solove();
printf("Case %d: %d\n",sss++,anx);
}
}
hdu4185 二分图之最大匹配
最新推荐文章于 2021-07-18 11:37:06 发布