From : http://www.tsinsen.com/ViewGProblem.page?gpid=A1105
问题描述
在一个地图上有N个地窖(N<=12),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。
[题目要求]
当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,每个地窖只能经过一次,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
[题目要求]
当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,每个地窖只能经过一次,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入格式
第一行一个数n。
第二行n个数wi表示每个点的地雷数。
随后n-1行若干个数。第i行第j个数表示i与i+j是否连通。1为连通,0为不连通。
第二行n个数wi表示每个点的地雷数。
随后n-1行若干个数。第i行第j个数表示i与i+j是否连通。1为连通,0为不连通。
输出格式
K1--K2--……….KV (挖地雷的顺序)
MAX=ans (挖地雷的数量)
如果有多种方案则输出字典序最小的方案。
MAX=ans (挖地雷的数量)
如果有多种方案则输出字典序最小的方案。
样例输入
5
10 8 4 7 6
1 1 1 1
0 0 0
1 1
1
10 8 4 7 6
1 1 1 1
0 0 0
1 1
1
样例输出
2-1-3-4-5
MAX=35
MAX=35
数据规模和约定
n<=12
解决方案:
基本思想: 深度优先搜索(DFS)或者称为回溯法(Backtracking)
下面是C语言源代码
1 #include <stdio.h> 2 3 #define M 12 4 5 typedef struct vector { 6 int len; 7 int data[M]; 8 } Vector; // 向量, 用来存储挖雷的顺序 9 10 11 int mine[M]; // mine[i] 表示第i个地窖中的地雷数,注意:这里i从0开始 12 int mark[M]; // 标记,mark[i] 表示第i个地窖是否已被挖过 13 int adjm[M][M]; // 邻接矩阵,表示地窖之间的连通关系 14 int N; // 地窖数 15 int cmax, max; // 分别为当前挖到的地雷数 和 能够挖到的最大地雷数 16 Vector cvector, vector; // cmax 和 max 对应的挖雷顺序 17 18 19 void sweep(int n) { 20 int i, j; 21 int flag = 1; 22 for (i = 0; i < N; i++) { 23 if (adjm[n][i] == 1 && mark[i] == 0) { 24 flag = 0; 25 mark[i] = 1; 26 cmax += mine[i]; 27 cvector.data[cvector.len++] = i; 28 sweep(i); 29 cvector.len--; 30 cmax -= mine[i]; 31 mark[i] = 0; 32 } 33 } 34 if (flag) { // 已挖到当前路径最大雷数 35 if (cmax > max) { 36 max = cmax; 37 vector.len = cvector.len; 38 for (j = 0; j < cvector.len; j++) { 39 vector.data[j] = cvector.data[j]; 40 } 41 } 42 } 43 } 44 45 46 int main() { 47 int i, j; 48 scanf("%d", &N); 49 for (i = 0; i < N; i++) { 50 scanf("%d", &mine[i]); 51 adjm[i][i] = 0; 52 mark[i] = 0; 53 } 54 for (i = 0; i < N; i++) { 55 for (j = i + 1; j < N; j++) { 56 scanf("%d", &adjm[i][j]); 57 adjm[j][i] = adjm[i][j]; 58 } 59 } 60 61 max = 0, cmax = 0; 62 for (i = 0; i < N; i++) { 63 cvector.data[0] = i; 64 cvector.len = 1; 65 cmax = mine[i]; 66 mark[i] = 1; 67 sweep(i); 68 mark[i] = 0; 69 } 70 71 printf("%d", vector.data[0] + 1); 72 for (i = 1; i < vector.len; i++) { 73 printf("-%d", vector.data[i] + 1); 74 } 75 printf(" MAX=%d ", max); 76 77 return 0; 78 }