最小生成樹

算法7-9:最小生成樹

時間限制: 1 Sec  內存限制: 32 MB

題目描述

最小生成樹問題是實際生產生活中十分重要的一類問題。假設須要在n個城市之間創建通訊聯絡網,則連通n個城市只須要n-1條線路。這時,天然須要考慮這樣一個問題,即如何在最節省經費的前提下創建這個通訊網。
能夠用連通網來表示n個城市以及n個城市之間可能設置的通訊線路,其中網的頂點表示城市,邊表示兩個城市之間的線路,賦於邊的權值表示相應的代價。對於n個頂點的連通網能夠創建許多不一樣的生成樹,每一棵生成樹均可以是一個通訊網。如今,須要選擇一棵生成樹,使總的耗費最小。這個問題就是構造連通網的最小代價生成樹,簡稱最小生成樹。一棵生成樹的代價就是樹上各邊的代價之和。
而在經常使用的最小生成樹構造算法中,普里姆(Prim)算法是一種很是經常使用的算法。如下是其算法的大體結構:
在本題中,讀入一個無向圖的鄰接矩陣(即數組表示),創建無向圖並按照以上描述中的算法創建最小生成樹,並輸出最小生成樹的代價。

輸入

輸入的第一行包含一個正整數n,表示圖中共有n個頂點。其中n不超過50。
之後的n行中每行有n個用空格隔開的整數,對於第i行的第j個整數,若是不爲0,則表示第i個頂點和第j個頂點有直接鏈接且代價爲相應的值,0表示沒有直接鏈接。當i和j相等的時候,保證對應的整數爲0。
輸入保證鄰接矩陣爲對稱矩陣,即輸入的圖必定是無向圖,且保證圖中只有一個連通份量。

輸出

只有一個整數,即最小生成樹的總代價。請注意行尾輸出換行。

樣例輸入

4
0 2 4 0
2 0 3 5
4 3 0 1
0 5 1 0

樣例輸出

6

提示

在本題中,須要掌握圖的深度優先遍歷的方法,並須要掌握無向圖的連通性問題的本質。經過求出無向圖的連通份量和對應的生成樹,應該可以對圖的連通性創建更加直觀和清晰的概念。

解題思路

這道題就是一道最小生成樹的純模板題。具體見代碼:
#include <stdio.h>
const int inf = 99999999;
int main()
{
    int n, data, sum, min, count;
    int map[55][55], vis[55], dis[55];
    while (~scanf("%d", &n))
    {
        sum = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                scanf("%d", &map[i][j]);
                if(i != j && !map[i][j])
                    map[i][j] = inf;
            }
        }
        for (int i = 0; i < n; i++)
        {
            dis[i] = map[0][i];
            vis[i] = 0;
        }
        vis[0] = count = 1;
        while (count < n)
        {
            min = inf;
            for (int i = 0; i < n; i++)
            {
                if (!vis[i] && dis[i] < min)
                {
                    min = dis[i];
                    data = i;
                }
            }
            vis[data] = 1;
            count++;
            sum += dis[data];
            for (int k = 0; k < n; k++)
            {
                if (!vis[k] && dis[k] > map[data][k])
                    dis[k] = map[data][k];
            }
        }
        printf("%d\n", sum);
    }
    return 0;
}
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息