合肥赛区的第二简单题
枚举原始农场的重建情况将剩下的点进行最大匹配求得独立集
注意不能连原始农场一起进行匹配,因为会形成有环图不是个二分图
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
int flag[105],link[105][105],used[105],n;
int max(int a,int b)
{
return a>b?a:b;
}
bool dfs(int pre)
{
for(int i=1;i<=n;i++)
if(!used[i]&&link[pre][i])
{
used[i] = 1;
if(!flag[i]||dfs(flag[i]))
{
flag[i] = pre;
return true;
}
}
return false;
}
int match()
{
int ans = 0;
memset(flag,0,sizeof(flag));
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
ans+=dfs(i);
}
return ans;
}
int sym[12],ans,mp1[12][12],n1,m1,link2[12][12];
int bu[4][2] = {0,1,0,-1,1,0,-1,0};
char mp[12][12];
void dfs1(int am,int pre)
{
//建图
int cnt = 0;
memset(mp1,0,sizeof(mp1));
memset(link,0,sizeof(link));
for(int i=0;i<n1;i++)
for(int j=0;j<m1;j++)
if(mp[i][j]=='.')
{
bool flag = true;
for(int k=0;k<4;k++)
{
int x = i+bu[k][0];
int y = j+bu[k][1];
if(x>=0&&x<n1&&y>=0&&y<m1&&mp[x][y]!='.'&&!sym[mp[x][y]-'0'])
{
flag = false;
break;
}
}
if(flag)mp1[i][j] = ++cnt;
}
n = cnt;
for(int i=0;i<n1;i++)
for(int j=0;j<m1;j++)
for(int k=0;k<4;k++)
{
int x = i+bu[k][0];
int y = j+bu[k][1];
if(x>=0&&x<n1&&y>=0&&y<m1)
link[mp1[i][j]][mp1[x][y]] = 1;
}
ans = max(am+n-match()/2,ans);
// 递归
for(int i = pre+1;i<=9;i++)
if(sym[i])
{
int flag = true;
for(int j=0;j<=pre;j++)
if(!sym[j]&&link2[i][j])
{
flag = false;
break;
}
if(flag)
{
sym[i] = 0;
dfs1(am+1,i);
sym[i] = 1;
}
}
}
int main()
{
int t,i1 = 1;
scanf("%d",&t);
while(t--)
{
ans = 0;
scanf("%d%d",&n1,&m1);
memset(sym,0,sizeof(sym));
memset(link2,0,sizeof(link2));
for(int i=0;i<n1;i++)scanf("%s",mp[i]);
for(int i=0;i<n1;i++)
for(int j=0;j<m1;j++)
if(mp[i][j]>='0'&&mp[i][j]<='9') {
sym[mp[i][j]-'0'] = 1;
}
for(int i=0;i<n1;i++)
for(int j=0;j<m1;j++)
for(int k=0;k<4;k++)
{
int x = bu[k][0]+i;
int y = bu[k][1]+j;
if(x>=0&&x<n1&&y>=0&&y<m1&&mp[x][y]!='.'&&mp[i][j]!='.')
{
link2[mp[x][y]-'0'][mp[i][j]-'0'] = 1;
link2[mp[i][j]-'0'][mp[x][y]-'0'] = 1;
}
}
dfs1(0,-1);
printf("Case #%d: ",i1);
i1++;
printf("%d\n",ans);
}
return 0;
}
//枚举方向写错dfs递归pre写错wa了好几发。。。