最小生成樹//poj Jungle Road

區別:
最小生成樹能夠保證整個圖所有路徑和最小,但不能保證任意兩點間是最短路徑。最短路徑是從一點出發,到達目的地路徑最短。

實現方法:
最通用:普里姆算法
先把給定定點加入集合,然後將集合內的頂點與集合外的頂點所構成的所有邊中選取權值最短的一條,並將集合外的頂點加入集合中,表示該頂點已連通。不斷循環。
它是一種與Dijkstra十分類似的算法,只不過每次找最短邊是在已經加入點的集合中找,而不是在新加入的點周圍擴展。
JungleRoad
模板題,附代碼

#include<stdio.h>
#include<string.h>
#include <iostream>
using namespace std;

#define inf 0xffffff
int map[30][30],n,dist[30];
bool vis[30];

int prim(){
    int i,j,mi,v;
    for(i=0;i<n;i++)
    {
        dist[i]=map[0][i];
        vis[i]=0;
    }
    for(i=1;i<=n;i++)
    {
        mi=inf;
        for(j=0;j<n;j++)
        {
            if(!vis[j] && mi>dist[j])
            {
                v=j;
                mi=dist[j];
            }
        }
        vis[v]=1;
        for(j=0;j<n;j++)
            if(!vis[j] && dist[j]>map[v][j])        
                    dist[j]=map[v][j];
    }
    for(i=1;i<n;i++) dist[0]+=dist[i];

    return dist[0];
}

int main(){
    int i,j,m,c;
    char a[2],b[2];
    while(scanf("%d",&n) && n)
    {
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
                if(i==j)
                    map[i][j]=0;
                else
                    map[i][j]=inf;
        for(i=1;i<n;i++)
        {
            scanf("%s%d ",&a,&m);
            for(j=0;j<m;j++)
            {
                scanf("%s%d ",&b,&c);
                map[a[0]-'A'][b[0]-'A']=map[b[0]-'A'][a[0]-'A']=c;
            }
        }
        cout<<prim()<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章