图论算法

1 prim 算法  O(n2) 贪心

/*
    最小生成树Prim 算法: 贪心思想,随机选择一个点当做最小生成树的初始节点,然后把图的顶点分成A集合(含初始节点), 
    B集合(剩余节点)每次选择A集合中的点到B集合中点的最短距离的边,然后用加入的点去松弛A集合点到B集合点的距离信息。不断迭代,
    最终得到最小生成树。
*/

struct Edge{
    int start_, end_;
    float weight_;
};

void prim(vector<vector<int>> &map, Edge *&mist){
    
    int n = map.size();
    if(n < 1) return ;
    mist = new Edge[n];
    if(mist == NULL) return ;
    
    for(int i - 0; i < n; ++i){
        mist[i].start_ = 0;
        mist[i].end_ = i;
        mist[i].weight_ = map[0][i];
    }
    
    for( int i = 1; i< n; ++i){
        
        int minWeight = mist[i].weight_;
        int minIndex = i;
        for(int j = i+1 ; j< n; ++j){
            if(mist[j].weight_ < minWeight){
                minWeight = mist[j].weight_;
                minIndex = j;
            }
        }
        
        if(minIndex != i){
            Edge tp = mist[i];
            mist[i] = mist[minIndex];
            mist[minIndex] = tp;
        }
        
        int x = mist[i].end_,y;
        for(int j = i+1; j<n; ++j){
            y = mist[j].end_;
            if(map[x][y] < mist[j].weight_){
                mist[j].start_ = x;
                mist[j].weight = map[x][y];
            }
        }
    }
}
View Code

2 最短路径dijkstra 算法 贪心思想

struct path{
    int pre;
    int length;
    path(){
        pre = -1;
        length = INT_MAX;
    }
};

void dijkstra(vector<vector<int>> &graph, path *&dist, int v){

    int n = graph.size();
    if(v < 0 || v >= n) return ;
    if(n == 0) return;
    dist = new path[n];
    if(dist == NULL) return ;
    for(int i = 1; i< n; ++i){
        if(graph[v][i] != INT_MAX){
            dist[i].pre = v;
            dist[i].length = graph[v][i];
        }
    }
    
    graph[v][v] = 1;
    
    for(int i = 1; i < n ; ++i){
    
        int min = -1, minLength = INT_MAX;
        for(int j = 0; j < n; ++j){
            if(graph[j][j] != 1 && dist[j].length < minLength){
                minLength = dist[j].length;
                min = j;
            }
        }
        if(min == -1) return ;
        graph[min][min] = 1;
        
        for(int j = 0; j< n;++j){
            if(graph[j][j] == 1) continue;
            int tp = dist[min].length + graph[min][j];
            if(tp < dist[j].length){
                dist[j].length = tp;
                dist[j].pre = min;
            }
        }
    }
}
View Code

3 floyd 非贪心 O(n3

 void floyd(vector<vector<int>> &graph, vector<vector<int>> &path){

    int n = graph.size();
    if(n == 0) return ;
    graph.resize(n, vector<int>(n));
    vector<vector<int>> p(n,vector<int>(n,0));
    
    for(int i = 0; i< n; ++i)
        for(int j = 0; j< n; ++j)
        {
            if(graph[i][j] != INT_MAX)
                path[i][j] = j;
            else
                path[i][j] = -1;
            p[i][j] = graph[i][j] ;
        }
    
    for(int k = 0; k< n; ++k)
        for(int i = 0; i< n; ++i)
            for(int j = 0; j< n; ++j)
            {
                if(p[i][k] == INT_MAX || p[k][j] == INT_MAX) continue;
                
                int tp = p[i][k] + p[k][j];
                if(tp < p[i][j]){
                    p[i][j] = tp;
                    path[i][j] = path[i][k];
                }
            }
}
原文地址:https://www.cnblogs.com/graph/p/3341098.html