1 #include <stdio.h>
2 #include <set>
3 #include <string.h>
4 #include <algorithm>
5 using namespace std;
6
7 const int maxn = 30;
8 const int inf = 999999999;
9 double minans;
10 int vis[maxn];//记录选中的点
11 int mp[maxn][maxn], ans[maxn][maxn];
12 int min_road[maxn];
13
14 int Prim(int n)
15 {
16 int i, j, min_i, minm, sum = 0;
17 int dis[maxn];
18 int vis[maxn];
19 for (i = 1; i <= n; i++)
20 dis[i] = ans[i][1];
21 memset(vis, false, sizeof vis);
22 vis[1] = true;
23 for (i = 1; i<n; i++)
24 {
25 minm = inf, min_i = i;
26 for (j = 1; j <= n; j++)
27 {
28 if (vis[j] == false && dis[j]<minm)
29 {
30 minm = dis[j];
31 min_i = j;
32 }
33 }
34 if (minm == inf)
35 break;
36 sum += minm;
37 vis[min_i] = true;
38 for (j = 1; j <= n; j++)
39 {
40 if (vis[j] == 0 && dis[j]>ans[min_i][j])
41 dis[j] = ans[min_i][j];
42 }
43 }
44 return sum;
45 }
46
47 int ok(int n)
48 {
49 memset(vis, 0, sizeof vis);
50 int cnt = 1;
51 int m = n, cont = 1;
52 while (m)
53 {
54 if (m % 2)
55 vis[cont++] = cnt;
56 cnt++;
57 m /= 2;
58 }
59 return cont;
60 }
61
62 int main()
63 {
64 int d[maxn], maxm;
65 int n, i, j, k, cnt, m;
66 while (scanf("%d%d", &n, &m) != EOF)
67 {
68 if (n == 0 && m == 0)
69 break;
70 maxm = 1;
71 for (i = 1; i <= n; i++)
72 maxm *= 2;
73 for (i = 1; i <= n; i++)
74 scanf("%d", &d[i]);
75 for (i = 1; i <= n; i++)
76 {
77 for (j = 1; j <= n; j++)
78 {
79 scanf("%d", &mp[i][j]);
80 }
81 }
82 minans = 9999999999.0;
83 int sum_point;
84 for (i = 0; i < maxm; i++)
85 {
86 if (ok(i) == m + 1)
87 {
88 sum_point = 0;
89 for (j = 1; j <= m; j++)
90 {
91 sum_point += d[vis[j]];//选的点
92 for (k = j + 1; k <= m; k++)
93 {
94 ans[j][k] = ans[k][j] = mp[vis[j]][vis[k]];
95 }
96 }
97 int sum = Prim(m);
98 if ((sum*1.0 / sum_point) < minans)
99 {
100 minans = sum*1.0 / sum_point;
101 for (i = 1; i <= m; i++)
102 min_road[i] = vis[i];
103 }
104 }
105 }
106 for (i = 1; i <= m - 1; i++)
107 printf("%d ", min_road[i]);
108 printf("%d\n", min_road[i]);
109 }
110 return 0;
111 }