HDU1863 最小生成樹 Prime

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1863

題解:裸的最小生成樹

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 2000 + 10;
int cnt = 0;
struct edge{
    int v;
    int len;
    int nex;
    edge(int a = 0, int b = 0, int c = -1):v(a), len(b), nex(c) {}
    bool operator <(const edge &a) const{
        return len > a.len;
    }
}e[maxn];
int id[maxn];
bool used[maxn];
void add(int from, int to, int len){
  e[cnt].v = to;
  e[cnt].len = len;
  e[cnt].nex = id[from];
  id[from] = cnt++;
}
void init(int n){
    for(int i = 0; i < n; i++){
        id[i] = -1;
    }
}
int Prime(int x, int n){
    memset(used, 0, sizeof(used));
    int tot = 0;///最小生成樹中的節點個數
    int sum = 0;
    priority_queue<edge> q;
    q.push(edge{x,0});
    while((tot < n) && !q.empty())
    {
        while(!q.empty()){
            edge mye = q.top();
            q.pop();
            if(!used[mye.v]){
                sum += mye.len;
                x = mye.v;
                used[x] = 1;
                tot++;
                for(int k = id[x]; ~k; k = e[k].nex){
                     if(!used[e[k].v])
                      q.push(e[k]);
                }
                   break;
            }
        }
    }
   if(tot == n)
    return sum;
   else return -1;
}
int main(){
    int n, m;
    while(scanf("%d%d", &m, &n), m){///m條路 n個點
        int a, b, c;
        init(n);
        for(int i = 0; i < m; i++){
            scanf("%d%d%d", &a, &b, &c);
            add(a, b, c);
            add(b, a, c);
        }
        int ans = Prime(1, n);
        if(ans != -1)
            printf("%d\n", ans);
        else
            printf("?\n");
    }
    return 0;
}
/*
14 9
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 4 14
6 3 4
3 9 2
9 7 6
7 6 2
7 8 1
8 9 7
8 2 11
8 1 8
*/


發佈了69 篇原創文章 · 獲贊 58 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章