思路是枚举+最小生成树,用DFS枚举或者二进制枚举。
/*
ID: sdj22251
PROG: calfflac
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAX 100000000
#define LOCA
#define PI acos(-1.0)
using namespace std;
int d[16][16], node[16], v[16], dis[16], ans[16];
int n, m;
double mi;
bool used[16];
void search()
{
int i, j, k, sum, weight;
sum = 0;
weight = 0;
memset(used, false, sizeof(used));
for(i = 0; i < m; i++)
dis[v[i]] = MAX;
for(i = 0; i < m; i++)
dis[v[i]] = d[v[0]][v[i]];
used[v[0]] = true;
for(i = 1; i < m; i++)
{
int mini = MAX;
int tmp = -1;
for(j = 0; j < m; j++)
if(!used[v[j]] && dis[v[j]] < mini)
{
mini = dis[v[j]];
tmp = v[j];
}
used[tmp] = true;
sum += mini;
for(j = 0; j < m; j++)
{
if(!used[v[j]] && d[v[j]][tmp] < dis[v[j]])
dis[v[j]] = d[v[j]][tmp];
}
}
for(j = 0; j < m; j++)
weight += node[v[j]];
double T = (double)sum / (double)weight;
if(T < mi)
{
for(j = 0; j < m; j++)
ans[j] = v[j];
mi = T;
}
}
void dfs(int x, int cnt)
{
v[cnt] = x;
if(cnt == m - 1)
{
search();
return;
}
for(int i = x + 1; i <= n; i++)
dfs(i, cnt + 1);
}
int main()
{
#ifdef LOCAL
freopen("ride.in","r",stdin);
freopen("ride.out","w",stdout);
#endif
int i, j;
while(scanf("%d%d", &n, &m) != EOF)
{
if(n == 0 && m == 0) break;
for(i = 1; i <= n; i++)
scanf("%d", &node[i]);
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
scanf("%d", &d[i][j]);
}
}
mi = 100000000.0;
for(i = 1; i <= n; i++)
dfs(i, 0);
for(i = 0; i < m - 1; i++)
printf("%d ", ans[i]);
printf("%d\n", ans[m - 1]);
}
return 0;
}