您的位置:首页 > 其它

【bzoj4554】[Tjoi2016&Heoi2016]游戏

2016-08-11 20:48 344 查看
现在问题有硬石头和软石头的限制

所以要对地图进行预处理

分行做,把有#隔开的*(x)形成联通块的存储下来。
分列作,把有#隔开的*(x)形成联通块的存储下来。

求出所有的行联通个数和列联通个数

作为二分图两边的点

求一遍最大匹配

#include<cstdio>
using namespace std;

typedef long long LL;

#define N 2500

struct edge
{
int to,next;
}e
;
int head
;
int cnt;

int vis
,ly
;

int xx[51][51],yy[51][51];

char ch[51][51];

int n,m;
int k1=1,k2=1;
int ans;

void link(int x,int y)
{
e[++cnt]=(edge){y,head[x]};
head[x]=cnt;
}

int dfs(int x,int d)
{
for (int i=head[x];i;i=e[i].next)
{
int t=e[i].to;
if (vis[t]==d)
continue;
vis[t]=d;
if (!ly[t] || dfs(ly[t],d))
{
ly[t]=x;
return true;
}
}
return false;
}

int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%s",ch[i]+1);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
if (ch[i][j]=='#')
k1++;
xx[i][j]=k1;
}
k1++;
}
for (int j=1;j<=m;j++)
{
for (int i=1;i<=n;i++)
{
if (ch[i][j]=='#')
k2++;
yy[i][j]=k2;
}
k2++;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (ch[i][j]=='*')
link(xx[i][j],yy[i][j]);
for (int i=1;i<=k1;i++)
ans+=dfs(i,i);
printf("%d\n",ans);
return 0;
}


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