poj 1287 heap+prime 最小生成树

 题目比较简单,可以不使用heap优化,这里作为练习

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. const int N = 600, INF = 1000000000;
  5. int dist[N], g[N][N], map[N], heap[3*N], del[N];
  6. int n, size;
  7. void heap_up(int root)
  8. {
  9.     int t = heap[root], fa = root>>1;
  10.     while(root > 1 && dist[t] < dist[heap[fa]])
  11.     {
  12.         heap[root] = heap[fa];
  13.         map[heap[root]] = root;
  14.         root = fa;
  15.         fa >>= 1;
  16.     }
  17.     heap[root] = t;
  18.     map[heap[root]] = root;
  19. }
  20. void heap_down(int root)
  21. {
  22.     int t = heap[root], ch = root<<1;
  23.     while(ch <= size)
  24.     {
  25.         if(ch+1 <= size && dist[heap[ch+1]] < dist[heap[ch]]) ch++;
  26.         if(dist[heap[ch]] < dist[t])
  27.         {
  28.             heap[root] = heap[ch];
  29.             map[heap[root]] = root;
  30.             root = ch;
  31.             ch <<= 1;
  32.         }
  33.         else break;
  34.     }
  35.     heap[root] = t;
  36.     map[heap[root]] = root;
  37. }
  38. int heap_pop()
  39. {
  40.     int t = heap[1];
  41.     heap[1] = heap[size--];
  42.     map[heap[1]] = 1;
  43.     heap_down(1);
  44.     return t;
  45. }
  46. int prime()
  47. {
  48.     int i, j, k, t, u;
  49.     for(i = 1; i <= n; i++)
  50.     {
  51.         dist[i] = INF;
  52.         heap[i] = i;
  53.         map[i] = i;
  54.         del[i] = 0;
  55.     }
  56.     size = n;
  57.     dist[1] = 0;
  58.     for(i = 1; i <= n; i++)
  59.     {
  60.         u = heap_pop();
  61.         del[u] = 1;
  62.         for(j = 1; j <= n; j++)
  63.         {
  64.             if(!del[j] && g[u][j] < dist[j])
  65.             {
  66.                 dist[j] = g[u][j];
  67.                 heap_up(map[j]);
  68.             }
  69.         }
  70.     }
  71.     for(i = 1, t = 0; i <= n; i++) t >?= dist[i];
  72.     return t;
  73. }
  74. /*
  75. 2
  76. 4
  77. 0 10 5 200
  78. 10 0 200 10
  79. 5 200 0 20
  80. 200 10 20 0
  81. ans=10
  82. */
  83. int main()
  84. {
  85.     int i, j, k, t;
  86.     scanf("%d", &t);
  87.     while(t--)
  88.     {
  89.         scanf("%d", &n);
  90.         for(i = 1; i <= n; i++)
  91.         {
  92.             for(j = 1; j <= n; j++)
  93.             {
  94.                 scanf("%d", &g[i][j]);
  95.             }
  96.             g[i][i] = INF;
  97.         }
  98.         printf("%d/n", prime());
  99.     }
  100.     return 0;
  101. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值