码迷,mamicode.com
首页 > 其他好文 > 详细

hdu2489 Minimal Ratio Tree dfs枚举组合情况+最小生成树

时间:2017-10-12 21:41:00      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:选中   div   return   point   printf   bre   minimal   names   amp   

  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 }

 

hdu2489 Minimal Ratio Tree dfs枚举组合情况+最小生成树

标签:选中   div   return   point   printf   bre   minimal   names   amp   

原文地址:http://www.cnblogs.com/jaydenouyang/p/7658034.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!