这题很明显可以用最大独立集来做,但是写代码很麻烦,是本人目前碰到的建图最麻烦的一道题,思路懒得写了,但是为代码应该很好懂。。。这里贴的代码的枚举没有优化所以更好懂。。。。需要卡两次时间才能过可能。上代码:
(时隔半年再次碰到这题,感觉还是比较棘手,底下贴一个稍微优化过的代码)
1.
#include<iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 110;
int n,m;
int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
int mmax;
int kn;
int bmap[maxn][maxn];
int bmask[maxn];
int nx,ny;
int cx[maxn];
int cy[maxn];
char g[12][12];
int id[12][12];
int vis[12][12];
int lianvis[12][12];
int bx[maxn];
int by[maxn];
vector<pair<int,int> > af[11];
int used[11];
int ans;
int findpath(int u )
{
int i;
for(i=1; i<=ny; i++)
{
if(by[i]==1)
if(bmap[u][i] && ! bmask[i])
{
bmask[i] = 1;
if(cy[i] == -1 || findpath(cy[i]))
{
cy[i] = u;
cx[u] = i;
return 1;
}
}
}
return 0;
}
int maxmatch()
{
int res(0);
int i,j;
for(i=1; i<=nx; i++)
{
cx[i]=-1;
}
for(j=1; j<=ny; j++)
{
cy[j]=-1;
}
for( i = 1; i <= nx ; i++ )
{
if(bx[i]==1)
if ( cx [ i ] == -1)
{
for(j = 1; j <= ny ; j++ )
{
bmask[j] = 0;
}
res+=findpath(i);
}
}
return res;
}
void dfs(int cnt)
{
if(cnt>=mmax+1)
{
memset(vis,0,sizeof(vis));
memset(lianvis,0,sizeof(lianvis));
int num=0,jian=0;
for(int i=0;i<=mmax;i++)
{
if(used[i]!=0)
{
if(af[i].size()>0)
num++;
for(int j=0;j<af[i].size();j++)
{
int xx=af[i][j].first,yy=af[i][j].second;
for(int kk=0;kk<4;kk++)
{
int x=xx+dir[kk][0],y=yy+dir[kk][1];
if(x<0||x>=n||y<0||y>=m)continue;
if(id[x][y]==0&&used[g[x][y]-'0']&&(g[x][y]-'0')!=i)
{
if(lianvis[g[x][y]-'0'][i]==0)
{
num--;
lianvis[g[x][y]-'0'][i]=lianvis[i][g[x][y]-'0']=1;
}
}
if(x<0||x>=n||y<0||y>=m||id[x][y]==0||vis[x][y])continue;
vis[x][y]=1;
jian++;
for(int k=0;k<4;k++)
{
int X=x+dir[k][0],Y=y+dir[k][1];
if(X<0||X>=n||Y<0||Y>=m||id[X][Y]==0)continue;
bmap[id[X][Y]][id[x][y]]=bmap[id[x][y]][id[X][Y]]=0;
}
}
}
}
}
int res=kn-jian-maxmatch()+num;
ans=max(ans,res);
for(int i=0;i<=mmax;i++)
{
if(used[i]!=0)
{
for(int j=0;j<af[i].size();j++)
{
int xx=af[i][j].first,yy=af[i][j].second;
for(int kk=0;kk<4;kk++)
{
int x=xx+dir[kk][0],y=yy+dir[kk][1];
if(x<0||x>=n||y<0||y>=m||id[x][y]==0)continue;
for(int k=0;k<4;k++)
{
int X=x+dir[k][0],Y=y+dir[k][1];
if(X<0||X>=n||Y<0||Y>=m||id[X][Y]==0)continue;
bmap[id[X][Y]][id[x][y]]=bmap[id[x][y]][id[X][Y]]=1;
}}
}
}
}
return;
}
else
{
used[cnt]=1;
dfs(cnt+1);
used[cnt]=0;
dfs(cnt+1);
}
}
int main()
{
int T;
int cns=0;
scanf("%d",&T);
while(T--)
{
mmax=-1;
memset(id,0,sizeof(id));
memset(used,0,sizeof(used));
memset(bx,0,sizeof(bx));
memset(by,0,sizeof(by));
for(int i=0;i<11;i++)
af[i].clear();
kn=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",g[i]);
for(int j=0;j<m;j++)
{
if(g[i][j]=='.')
{
id[i][j]=++kn;
if((i+j)%2==0)
bx[kn]=1;
else
by[kn]=1;
}
else
{
mmax=max(mmax,g[i][j]-'0');
af[g[i][j]-'0'].push_back(make_pair(i,j));
}
}
}
nx=kn;
ny=kn;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(id[i][j]!=0)
{
for(int k=0;k<4;k++)
{
int X=i+dir[k][0];
int Y=j+dir[k][1];
if(X<0||X>=n||Y<0||Y>=m||id[X][Y]==0)continue;
bmap[id[i][j]][id[X][Y]]=1;
}
}
}
ans=-1;
dfs(0);
cout<<"Case #"<<++cns<<": "<<ans<<endl;
for(int j=0; j<=nx; j++)
{
for(int k=0; k<=ny; k++)
{
bmap[j][k]=0;
}
}
}
}
2.
#include<iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 110;
int n,m;
int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
int mmax;
int kn;
int bmap[maxn][maxn];
int bmask[maxn];
int nx,ny;
char g[12][12];
int id[12][12];
int vis[12][12];
int lianvis[12][12];
int bx[maxn];
int by[maxn];
vector<pair<int,int> > af[11];
int used[11];
int ans;
int linker[maxn];
int used1[maxn];
bool dfs1(int u)
{
int v;
for(v=1;v<=ny;v++)
if(bmap[u][v]&&!used1[v])
{
used1[v]=true;
if(linker[v]==-1||dfs1(linker[v]))
{
linker[v]=u;
return true;
}
}
return false;
}
int hungary()
{
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for(u=1;u<=nx;u++)
{
if(bx[u]==1)
{memset(used1,0,sizeof(used1));
if(dfs1(u)) res++;}
}
return res;
}
void dfs(int cnt)
{
if(cnt>=mmax+1)
{
memset(vis,0,sizeof(vis));
memset(lianvis,0,sizeof(lianvis));
int num=0,jian=0;
for(int i=0;i<=mmax;i++)
{
if(used[i]!=0)
{
if(af[i].size()>0)
num++;
for(int j=0;j<af[i].size();j++)
{
int xx=af[i][j].first,yy=af[i][j].second;
for(int kk=0;kk<4;kk++)
{
int x=xx+dir[kk][0],y=yy+dir[kk][1];
if(x<0||x>=n||y<0||y>=m)continue;
if(id[x][y]==0&&used[g[x][y]-'0']&&(g[x][y]-'0')!=i)
{
if(lianvis[g[x][y]-'0'][i]==0)
{
num--;
lianvis[g[x][y]-'0'][i]=lianvis[i][g[x][y]-'0']=1;
}
}
if(x<0||x>=n||y<0||y>=m||id[x][y]==0||vis[x][y])continue;
vis[x][y]=1;
jian++;
for(int k=0;k<4;k++)
{
int X=x+dir[k][0],Y=y+dir[k][1];
if(X<0||X>=n||Y<0||Y>=m||id[X][Y]==0)continue;
bmap[id[X][Y]][id[x][y]]=bmap[id[x][y]][id[X][Y]]=0;
}
}
}
}
}
int res=kn-jian-hungary()+num;
ans=max(ans,res);
for(int i=0;i<=mmax;i++)
{
if(used[i]!=0)
{
for(int j=0;j<af[i].size();j++)
{
int xx=af[i][j].first,yy=af[i][j].second;
for(int kk=0;kk<4;kk++)
{
int x=xx+dir[kk][0],y=yy+dir[kk][1];
if(x<0||x>=n||y<0||y>=m||id[x][y]==0)continue;
for(int k=0;k<4;k++)
{
int X=x+dir[k][0],Y=y+dir[k][1];
if(X<0||X>=n||Y<0||Y>=m||id[X][Y]==0)continue;
bmap[id[X][Y]][id[x][y]]=bmap[id[x][y]][id[X][Y]]=1;
}}
}
}
}
return;
}
else
{
used[cnt]=1;
dfs(cnt+1);
used[cnt]=0;
dfs(cnt+1);
}
}
int main()
{
int T;
int cns=0;
scanf("%d",&T);
while(T--)
{
mmax=-1;
memset(id,0,sizeof(id));
memset(used,0,sizeof(used));
memset(bx,0,sizeof(bx));
memset(by,0,sizeof(by));
for(int i=0;i<11;i++)
af[i].clear();
kn=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",g[i]);
for(int j=0;j<m;j++)
{
if(g[i][j]=='.')
{
id[i][j]=++kn;
if((i+j)%2==0)
bx[kn]=1;
else
by[kn]=1;
}
else
{
mmax=max(mmax,g[i][j]-'0');
af[g[i][j]-'0'].push_back(make_pair(i,j));
}
}
}
nx=kn;
ny=kn;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(id[i][j]!=0)
{
for(int k=0;k<4;k++)
{
int X=i+dir[k][0];
int Y=j+dir[k][1];
if(X<0||X>=n||Y<0||Y>=m||id[X][Y]==0)continue;
bmap[id[i][j]][id[X][Y]]=1;
}
}
}
ans=-1;
dfs(0);
cout<<"Case #"<<++cns<<": "<<ans<<endl;
for(int j=0; j<=nx; j++)
{
for(int k=0; k<=ny; k++)
{
bmap[j][k]=0;
}
}
}
}