Dijkstra VS. Prim

Dijkstra & Prim 都是贪心算法的一种应用,在代码层面,你会发现他们很像,相异点仅一两行。


Dijkstra

void dijkstra(void){
    memset(visited,0,sizeof(visited));
    memset(path,0,sizeof(path));
    for(int i=1;i<=N;i++)
        dist[i]=INF;
    int src=1;
    visited[src]=true;
    path[1]=1;
    dist[1]=0;
    int next=src,min=INF;
    for(int i=1;i<N;i++){
        for(int j=1;j<=N;j++){
            if(!visited[j] && c[next][j] != INF && dist[next]+c[next][j]<dist[j]){
                dist[j]=dist[next]+c[next][j];
                path[j]=next;
            }
        }
        min=INF;
        for(int j=1;j<=N;j++){
            if(!visited[j] && dist[j]<min){
                min=dist[j];
                next=j;
            }
        }
        visited[next]=true;
    }
}


Prim_MST

void Prim(void){
    memset(visited,0,sizeof(visited));
    memset(path,0,sizeof(path));
    for(int i=1;i<=N;i++)
        dist[i]=INF;
    int src=1;
    visited[src]=true;
    path[1]=1;
    dist[1]=0;
    int next=src,min=INF;
    for(int i=1;i<N;i++){
        for(int j=1;j<=N;j++){
            if(!visited[j] && c[next][j] != INF && c[next][j]<dist[j]){
                dist[j]=c[next][j];
                path[j]=next;
            }
        }
        min=INF;
        for(int j=1;j<=N;j++){
            if(!visited[j] && dist[j]<min){
                min=dist[j];
                next=j;
            }
        }
        visited[next]=true;
    }
}


相异在:第13/14行,dist[next] 在Dijkstra加了,Prim不需要。

Prim_MST要求的是点与点之间的距离,所以无需像Dij那样需要加上以前的长度。

MST中,Prim针对的是点,Krustal针对的是边



####2014/10/28 update

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

    int data[7][7]={
        {0,0,0,0,0,0,0},
        {0,0,1,2,0,0,0},
        {0,1,0,0,1,2,0},
        {0,2,0,0,4,0,6},
        {0,0,1,4,0,5,5},
        {0,0,2,0,5,0,1},
        {0,0,0,6,5,1,0} };

//NOTE:
//1. Dijkstra dij(vertex,src);
//2. dij.work();
class Dijkstra{
public:
    Dijkstra(int n, int src):vertex_(n),src_(src){
        visited_.assign(vertex_+1,0);
        path_.assign(vertex_+1,0);
        dist_.assign(vertex_+1,999);//999 could be INF
    }
    void work(){
        //init src_ data
        visited_[src_]=true;
        path_[src_]=src_;
        dist_[src_]=0;

        int min,next=src_;
        for(int i=1;i<=vertex_;++i){
            //go through around, update dist_ using minimun distance
            for(int j=1;j<=vertex_;++j){
                if(!visited_[j] && data[next][j] != 0 && dist_[next]+data[next][j]<dist_[j]){
                    dist_[j]=dist_[next]+data[next][j];
                    path_[j]=next;
                }
            }
            min=999;
            //find the next stop 
            for(int k=1;k<=vertex_;++k){
                if(!visited_[k] && dist_[k]<min){
                    min=dist_[k];
                    next=k;
                }
            }
            //found next and enable visited
            //"next" is the another source stop
            visited_[next]=true;
        }
    }
    void getDistance(vector<int> &tmp){
        tmp.assign(dist_.begin(),dist_.end());
    }
    void printDistance(int index){
        cout<<"distance["<<index<<"]:"<<dist_[index]<<endl;
    }
    void printPath(int index){
        stack<int> s;
        int i = index;
        s.push(i);
        while(path_[i]!=src_){
            s.push(path_[i]);
            i = path_[i];
        }
        s.push(src_);
        //data ready, print the stack
        while(!s.empty()){
            cout<<"->"<<s.top();
            s.pop();
        }
        cout<<endl;
    }
    void printVec(vector<int> vec){
        vector<int>::iterator it=vec.begin()+1;
        for(;it!=vec.end();++it)
            cout<<*it<<" ";
        cout<<endl;
    }
private:
    vector<int> visited_;
    vector<int> path_;
    vector<int> dist_;
    int vertex_;//how many vertex
    int src_;//fron src
};




int main(void){
    Dijkstra dij(6,1);
    dij.work();

    dij.printDistance(6);
    dij.printPath(6);

    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值