noip1996 挖地雷 - 提高组 (搜索)

A1105. 挖地雷
时间限制: 1.0s   内存限制: 256.0MB  
总提交次数: 557   AC次数: 206   平均分: 55.33
将本题分享到:
       
   
试题来源
  NOIP1996 提高组
问题描述
  在一个地图上有N个地窖(N<=12),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。

  [题目要求]
  当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,每个地窖只能经过一次,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入格式
  第一行一个数n。
  第二行n个数wi表示每个点的地雷数。
  随后n-1行若干个数。第i行第j个数表示i与i+j是否连通。1为连通,0为不连通。
输出格式
  K 1--K 2--……….K (挖地雷的顺序)
  MAX=ans (挖地雷的数量)
  如果有多种方案则输出字典序最小的方案。
样例输入
5
10 8 4 7 6
1 1 1 1
0 0 0
1 1
1
样例输出
2-1-3-4-5
MAX=35
数据规模和约定
  n<=12
解析:搜索。
      用c[]来记录搜索顺序。
      dfs(step,p,w) :step  搜索了几个地窖
                       p     上次搜索的地窖编号为 p 
                       w     目前总共搜到的地雷。
代码:
</pre><pre name="code" class="cpp">#include<cstdio>
#include<cstdlib>
#define maxn 12
using namespace std;
int a[maxn+10],n,sum=0;
int b[maxn+10],c[maxn+10],ans=0;
bool map[maxn+5][maxn+5],used[maxn+5];

void write_ans()
{
  int i,j,k;
  for(i=1;i<b[0];i++)printf("%d-",b[i]);
  printf("%d\n",b[b[0]]);
  printf("MAX=%d\n",ans);  
}

void dfs(int step,int p,int w)
{
  bool flag=0;
  int i,j,k;
  for(i=1;i<=n;i++)
    if(!used[i] && map[p][i])
      {
        flag=1;
        c[step+1]=i,used[i]=1;
        dfs(step+1,i,w+a[i]);
        used[i]=0;
      }
  if(!flag &&  w>ans)
    {
      for(b[0]=step,i=1;i<=b[0];i++)b[i]=c[i];
      ans=w;
      if(ans==sum)
       {
         write_ans();
         exit(0);
       }
    }    
}

int main()
{
  int i,j,k;
  scanf("%d",&n);
  for(i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];
  for(i=1;i<n;i++)
    for(j=1;i+j<=n;j++)
      {
        scanf("%d",&k);
        map[i][i+j]=map[i+j][i]=k;
      }    
  for(i=1;i<=n;i++)used[i]=1,c[1]=i,dfs(1,i,a[i]),used[i]=0;
  write_ans();  
  return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值