题目描述
在一个地图上有N个地窖(N≤20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入格式
有若干行。
第1行只有一个数字,表示地窖的个数N。
第2行有N个数,分别表示每个地窖中的地雷个数。
第3行至第N+1行表示地窖之间的连接情况:
第3行有n−1个数(0或1),表示第一个地窖至第2个、第3个、…、第n个地窖有否路径连接。如第3行为11000 …0,则表示第1个地窖至第2个地窖有路径,至第3个地窖有路径,至第4个地窖、第5个、…、第n个地窖没有路径。
第4行有n−2个数,表示第二个地窖至第3个、第4个、…、第n个地窖有否路径连接。
… …
第n+1行有1个数,表示第n−1个地窖至第n个地窖有否路径连接。(为0表示没有路径,为1表示有路径)。
输出格式
有两行
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。
输入输出样例
输入
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
输出
1 3 4 5
27
思路:很明显的一道DFS题,但是增加了一个问题,怎么记录路径?这个关键是判断这个找地洞什么时候结束,结束的时候将路径保存进一个数组即可。写好check函数就好,即那个洞窟没有其他可到达的洞窟。
代码如下:
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int lei_num[22];
int link[21][21];
int path[22];
int res[22];
int max_lei=-1,N,len;
int visited[22];
bool check(int x)
{
int i;
for(i=1;i<=N;i++)
{
if(link[x][i]&&!visited[i])//说明有洞可通
return false;
}
return true;//没有洞可通
}
void dfs(int start,int count,int step)
{
int i;
//cout << "为" << count << endl;
if(check(start))//说明没洞可钻了
{
if(max_lei<count)
{
max_lei=count;
len=step+1;
for(i=0;i<len;i++)
res[i]=path[i];
}
return;
}
for(i=1;i<=N;i++)
{
if(!visited[i]&&link[start][i]==1)//没有去过这个洞且可以去
{
visited[i]=1;
path[step+1]=i;
dfs(i,count+lei_num[i],step+1);
visited[i]=0;
}
}
}
int main()
{
int i,j;
cin >> N;
for(i=1;i<=N;i++)
cin >> lei_num[i];
memset(link,0,sizeof(link));
for(i=1;i<N;i++)
{
for(j=i+1;j<=N;j++)
{
cin >> link[i][j];
//link[j][i]=link[i][j];
}
}
for(i=1;i<=N;i++)
{
memset(visited,0,sizeof(visited));
path[0]=i;
visited[i]=1;
dfs(i,lei_num[i],0);
visited[i]=0;
}
for(i=0;i<len-1;i++)
cout << res[i] << " ";
cout << res[len-1] << endl;
cout << max_lei << endl;
return 0;
}