hdu 5556 Land of Farms(最大独立集)

11 篇文章 0 订阅
1 篇文章 0 订阅

这题很明显可以用最大独立集来做,但是写代码很麻烦,是本人目前碰到的建图最麻烦的一道题,思路懒得写了,但是为代码应该很好懂。。。这里贴的代码的枚举没有优化所以更好懂。。。。需要卡两次时间才能过可能。上代码:
(时隔半年再次碰到这题,感觉还是比较棘手,底下贴一个稍微优化过的代码)
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;
                  }
            }
      }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值