Hdu2489Minimal Ratio Tree Minimum Spanning Tree
// For a complete graph, find a tree in it, so that the sum of the edge weights divided by the sum of the vertex weights is the smallest // due to n <= 15, if you enumerate all selected vertices in brute force mode, find the Minimum Spanning Tree from these vertices # include
# Include
# Include
Using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 20; int vis [maxn]; int dis [maxn]; int tmp [maxn]; int w [maxn]; int a [maxn]; int map [maxn] [maxn]; int n, m; int prim () {int pos; memcpy (tmp, vis, sizeof (vis )); for (int I = 1; I <= n; I ++) if (! Vis [I]) {vis [I] = 1; pos = I; break;} for (int I = 1; I <= n; I ++) dis [I] = I = pos? 0: map [pos] [I]; int ans = 0; while (1) {int mi = inf; for (int I = 1; I <= n; I ++) if (! Vis [I] & dis [I] <mi) mi = dis [pos = I]; if (mi = inf) break; vis [pos] = 1; ans + = mi; for (int I = 1; I <= n; I ++) if (! Vis [I]) dis [I] = min (dis [I], map [pos] [I]);} memcpy (vis, tmp, sizeof (tmp )); return ans;} double ans = inf; void dfs (int pos, int num, double sum) {if (num = m) {double sum_e = prim (); if (sum_e/sum <ans) {ans = sum_e/sum; memcpy (a, vis, sizeof (vis) ;}return ;}for (int I = pos; I <= n; I ++) {if (! Vis [I]) continue; vis [I] = 0; dfs (I, num + 1, sum + w [I]); vis [I] = 1 ;}} int main () {// freopen(in.txt, r, stdin); while (scanf (% d, & n, & m) & (n + m )) {for (int I = 1; I <= n; I ++) scanf (% d, & w [I]); for (int I = 1; I <= n; I ++) for (int j = 1; j <= n; j ++) scanf (% d, & map [I] [j]); for (int I = 1; I <= n; I ++) vis [I] = 1; ans = inf; dfs (1,0, 0); int flag = 0; for (int I = 1; I <= n; I ++) if (! A [I]) {if (flag) printf (); printf (% d, I); flag = 1 ;}puts () ;}return 0 ;}