题目描述
在一个地图上有NNN个地窖(N≤20)(N \le 20)(N≤20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入格式
有若干行。
第111行只有一个数字,表示地窖的个数NNN。
第222行有NNN个数,分别表示每个地窖中的地雷个数。
第333行至第N+1N+1N+1行表示地窖之间的连接情况:
第333行有n−1n-1n−1个数(000或111),表示第一个地窖至第222个、第333个、…、第nnn个地窖有否路径连接。如第333行为11000…01 1 0 0 0 … 011000…0,则表示第111个地窖至第222个地窖有路径,至第333个地窖有路径,至第444个地窖、第555个、…、第nnn个地窖没有路径。
第444行有n−2n-2n−2个数,表示第二个地窖至第333个、第444个、…、第nnn个地窖有否路径连接。
… …
第n+1n+1n+1行有111个数,表示第n−1n-1n−1个地窖至第nnn个地窖有否路径连接。(为000表示没有路径,为111表示有路径)。
输出格式
有两行
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。
输入输出样例
输入 #1
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
输出 #1
1 3 4 5
27
思路
一看到题目我就直接想到了dfs暴力搜索,自己搜了一遍但是不会记录路径,后来看了大佬的题解,才知道原来可以这样子记录路径,学到了,等会要去学一下dp的正规解法。
#include<iostream>
using namespace std;
bool f[21][21];//记录是否有路径相连
int a[21];//记录地雷数
int path[21],ans[21],cnt;//path记录路径,ans记录答案,cnt记录走了多少个点
bool b[21];//记录该点是否走过
int n;
int maxx;//记录最大地雷数
bool chck(int x)//检查是否还能往下挖
{
for(int i=1;i<=n;i++)
{
if(f[x][i]&&!b[i])return false;
}
return true;
}
void dfs(int x,int stp,int sum)
{
if(chck(x))
{
if(maxx<sum)
{
maxx=sum;
cnt=stp;
for(int i=1;i<=stp;i++)
{
ans[i]=path[i];
}
}
}
for(int i=1;i<=n;i++)
{
if(f[x][i]&&!b[i])
{
b[i]=1;
path[stp+1]=i;//记录路径
dfs(i,stp+1,sum+a[i]);
b[i]=0;
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
cin>>f[i][j];
}
}
for(int i=1;i<=n;i++)
{
b[i]=1;
path[1]=i;
dfs(i,1,a[i]);
b[i]=0;
}
for(int i=1;i<=cnt;i++)
{
cout<<ans[i]<<" ";
}
cout<<endl<<maxx;
return 0;
}