心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0
题目大意:给出一个Graph,要给这个Graph上面的vertex涂色,颜色只有两种:黒和白。相邻的两个vertex不能全涂成黑色。要求黑色的最多。
不要被此题n=100的数据规模吓倒,100的规模也是可以搜索的,数据也似乎不是很强。我的做法是依次枚举每个顶点的状态,即是黑色还是白色,这里有两个优化:1、显而易见的,如果结点i有邻接结点已经是黑色了,那么i只能是白色;2、最优性剪枝:如果当前搜索到dep层,其中now个结点被涂色,已经搜索出的最优解为ans,如果now+v-dep+1<=ans,就不需要再继续搜索下去了,此时是假设以后的(v-dep+1)个结点全部涂成黑色,即理想状况。
以下是我的代码:
#include<stdio.h>
const long maxv=102;
long v,e,ans,a[maxv];
bool g[maxv][maxv];
int d[maxv];
bool ok(long node)
{
    
for(long i=1;i<=v;i++)
      
if(g[node][i]&&d[i]==1)
        
return false;
    
return true;
}
void dfs(long dep,long now)
{
    
if(dep>v)
    {
       
if(now>ans)
       {
          ans
=now;
          
for(long i=1;i<=v;i++) a[i]=d[i];
       }
       
return;
    }
    
if(now+v-dep+1<=ans) return;
    
    
if(ok(dep))
    {
       d[dep]
=1;
       dfs(dep
+1,now+1);
       d[dep]
=0;
    }
    dfs(dep
+1,now);
}
int main()
{
    
/*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    //
*/
    
long test;
    
bool first;
    scanf(
"%ld",&test);
    
while(test--)
    {
       scanf(
"%ld%ld",&v,&e);
       
for(long i=0;i<=v;i++)
         
for(long j=0;j<=v;j++)
           g[i][j]
=false;
       
for(long i=0;i<=v;i++) d[i]=0;
       ans
=0;
       
//  Clear
       for(long i=1;i<=e;i++)
       {
          
long a,b;
          scanf(
"%ld%ld",&a,&b);
          g[a][b]
=g[b][a]=true;
       }
       dfs(
1,0);
       printf(
"%ld\n",ans);
       first
=true;
       
for(long i=1;i<=v;i++)
         
if(a[i])
         {
            
if(first) first=false;
            
else putchar(' ');
            printf(
"%ld",i);
         }
       putchar(
'\n');
    }
return 0;
}


posted on 2010-01-09 22:19 lee1r 阅读(948) 评论(0)  编辑 收藏 引用 所属分类: 题目分类:搜索

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理