poj 1287 && la 2515

題目概述

有P個地點,R條雙向路,求其最小生成樹邊權和

時限

1000ms/3000ms

輸入

第一行整數P,R,其後R行,每行三個整數a,b,c,描述a到b之間的一條路徑,權值爲c,輸入到P=0結束

限制

1<=P<=50;1<=R<=100

輸出

每行一個數,爲所求邊權和

樣例輸入

1 0

2 3
1 2 37
2 1 17
1 2 68

3 7
1 2 19
2 3 11
3 1 7
1 3 5
2 3 89
3 1 91
1 2 32

5 7
1 2 5
2 3 7
2 4 8
4 5 11
3 5 10
1 5 6
4 2 12

0

樣例輸出

0
17
16
26

討論

圖論,最小生成樹,prim算法,沒什麼說的,很直白,求就是
由於題目相當直白,因此再轉述也沒什麼意思,直接就把模型抽象好了

題解狀態

176K,16MS,C++,1028B

題解代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 52
#define memset0(a) memset(a,0,sizeof(a))

int P, R;//地點總數 路徑總數
int graph[MAXN][MAXN], dis[MAXN];//鄰接矩陣 兩點間最短距離
bool mk[MAXN];//已在樹中的標記
int fun()
{
    for (int p = 1; p <= P; p++)
        for (int i = p + 1; i <= P; i++)
            graph[p][i] = graph[i][p] = INF;//初始化鄰接矩陣
    for (int p = 0; p < R; p++) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);//input
        graph[a][b] = graph[b][a] = min(graph[a][b], c);
    }
    int sum = 0;//邊權和
    for (int p = 1; p <= P; p++) {
        dis[p] = graph[1][p];//初始化最短距離數組
        mk[p] = 0;
    }
    mk[1] = 1;//第一個點加入樹 下面是prim主體
    for (int p = 1; p < P; p++) {
        int least = INF, pos;
        for (int p = 1; p <= P; p++)
            if (!mk[p] && least>dis[p]) {
                least = dis[p];
                pos = p;
            }
        mk[pos] = 1;
        sum += least;
        for (int p = 1; p <= P; p++)
            if (!mk[p] && dis[p] > graph[pos][p])
                dis[p] = graph[pos][p];
    }
    return sum;
}
int main(void)
{
    //freopen("vs_cin.txt", "r", stdin);
    //freopen("vs_cout.txt", "w", stdout);

    while (~scanf("%d%d", &P, &R) && P) {//input
        printf("%d\n", fun());//output
    }
}

EOF

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