poj 1789 Truck History

本文介绍了一个简单的最小生成树(MST)问题解决方案,并提供了详细的C++代码实现。该问题需要计算节点间的差异并利用Prim算法找到最小生成树,最终输出最高可能的质量分数。

http://poj.org/problem?id=1789

  简单MST,要注意cnt和size清零!

View Code
  1 #include <cstdio>
  2 #include <iostream>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 const int MAXV = 2005, MAXE = 2005 * 2005, INF = (~0u)>>2;
  7 char car[MAXV][10];
  8 struct edge{
  9     int t, w, next;
 10 }es[MAXE];
 11 int h[MAXV], cnt, n, heap[MAXV], size, pos[MAXV], dist[MAXV];
 12 
 13 void init(){
 14     cnt = size = 0;
 15     memset(h, 0, sizeof(h));
 16     memset(heap, 0, sizeof(heap));
 17     memset(pos, 0, sizeof(pos));
 18     memset(dist, 0, sizeof(dist));
 19 }
 20 
 21 void addedge(int x, int y, int z){
 22     es[++cnt].t = y;
 23     es[cnt].next = h[x];
 24     es[cnt].w = z;
 25     h[x] = cnt;
 26 }
 27 
 28 void heapup(int k){
 29     while(k > 1){
 30         if(dist[heap[k >> 1]] > dist[heap[k]]){
 31             swap(pos[heap[k >> 1]], pos[heap[k]]);
 32             swap(heap[k >> 1], heap[k]);
 33             k >>= 1;
 34         }
 35         else break;
 36     }
 37 }
 38 void heapdown(int k){
 39     while((k << 1) <= size){
 40         int j;
 41         if((k << 1) == size || dist[heap[k << 1]] < dist[heap[k << 1 | 1]])
 42             j = k << 1;
 43         else
 44             j = k << 1 | 1;
 45         if(dist[heap[k]] > dist[heap[j]]){
 46             swap(pos[heap[k]], pos[heap[j]]);
 47             swap(heap[k], heap[j]);
 48             k = j;
 49         }
 50         else break;
 51     }
 52 }
 53 void push(int v, int d){
 54     dist[v] = d;
 55     heap[++size] = v;
 56     pos[v] = size;
 57     heapup(size);
 58 }
 59 
 60 int pop(){
 61     int ret = heap[1];
 62     swap(pos[heap[size]], pos[heap[1]]);
 63     swap(heap[size], heap[1]);
 64     size--;
 65     heapdown(1);
 66     return ret;
 67 }
 68 
 69 int prim(){
 70     int mst = 0, i, p;
 71 
 72     push(1, 0);
 73     for(i = 2; i <= n; i++)
 74         push(i, INF);
 75     for(i = 1; i <= n; i++){
 76         int t = pop();
 77         mst += dist[t];
 78         pos[t] = -1;
 79         for(p = h[t]; p; p = es[p].next){
 80             int dst = es[p].t;
 81             if(pos[dst] != -1 && dist[dst] > es[p].w){
 82                 dist[dst] = es[p].w;
 83                 heapup(pos[dst]);
 84                 heapdown(pos[dst]);
 85             }
 86         }
 87     }
 88     return mst;
 89 }
 90 
 91 int diff(char *a, char *b){
 92     int ret = 0;
 93 
 94     for (int i = 0; i < 7; i++){
 95         ret += (a[i] != b[i]);
 96     }
 97 
 98     return ret;
 99 }
100 
101 void deal(){
102     int c;
103 
104     for (int i = 1; i <= n; i++){
105         scanf("%s", car[i]);
106         for (int j = 1; j < i; j++){
107             c = diff(car[i], car[j]);
108             addedge(i, j, c);
109             addedge(j, i, c);
110         }
111     }
112     printf("The highest possible quality is 1/%d.\n", prim());
113 }
114 
115 int main(){
116 #ifndef ONLINE_JUDGE
117     freopen("in", "r", stdin);
118 #endif
119     while (~scanf("%d", &n) && n){
120         init();
121         deal();
122     }
123 
124     return 0;
125 }

 

——written by Lyon

转载于:https://www.cnblogs.com/LyonLys/archive/2012/08/26/poj_1789_Lyon.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值