码迷,mamicode.com
首页 > 其他好文 > 详细

最短路径

时间:2016-04-07 20:57:07      阅读:323      评论:0      收藏:0      [点我收藏+]

标签:

多源最短路径

c.floyd

技术分享
/*
多源最短路径
floyd
*/
#include<iostream>
#include<stdio.h>
using namespace std;

#define MAXN 1010
#define typec int
#define INF 0x3f3f3f3f//防止后面溢出,这个不能太大
int path[MAXN][MAXN];
int cost[MAXN][MAXN],lowcost[MAXN][MAXN];

void floyd(typec cost[][MAXN],typec lowcost[][MAXN],int n){
    int i,j,k;
    for(i=0;i<n;++i)
        for(j=0;j<n;++j){
            lowcost[i][j]=cost[i][j];
            if(i!=j&&cost[i][j]<INF)path[i][j]=i;
            else path[i][j]=-1;
        }
    for(k=0;k<n;++k)
        for(i=0;i<n;++i)
            for(j=0;j<n;++j)
                if(lowcost[i][k]+lowcost[k][j]<lowcost[i][j]){
                    lowcost[i][j]=lowcost[i][k]+lowcost[k][j];
                    path[i][j]=path[k][j];
                }
}

int main(){
    int n,m;//点数,边数
    int a,b,w,i,j;
    int s,t;//起点,终点

    while(~scanf("%d%d",&n,&m)){
        for(i=0;i<n;++i)
            for(j=0;j<n;++j)
                cost[i][j]=INF;
        for(i=0;i<m;++i){
            scanf("%d%d%d",&a,&b,&w);
            if(w<cost[a][b])cost[a][b]=cost[b][a]=w;//
        }
        scanf("%d%d",&s,&t);
        floyd(cost,lowcost,n);
        if(s==t)printf("0\n");
        else if(lowcost[s][t]!=INF)printf("%d\n",lowcost[s][t]);
        else printf("-1\n");
    }
    return 0;
}
View Code

 

-----------------------

c.Dijkstra单源最短路

技术分享
/*
Dijkstra单源最短路
权值必须是非负
单源最短路径,Dijkstra算法,邻接矩阵形式,复杂度为O(n^2)
求出源beg到所有点的最短路径,传入图的顶点数,和邻接矩阵cost[][]
返回各点的最短路径lowcost[],路径pre[].pre[i]记录beg到i路径上的父结点,pre[beg]=-1
可更改路径权类型,但是权值必须为非负
*/
#include<iostream>
#include<stdio.h>
using namespace std;

const int MAXN=1010;
#define typec int
const typec INF=0x3f3f3f3f;//防止后面溢出,这个不能太大
bool vis[MAXN];
int pre[MAXN];
void Dijkstra(typec cost[][MAXN],typec lowcost[],int n,int beg){
    for(int i=0;i<n;i++){
        lowcost[i]=INF;vis[i]=false;pre[i]=-1;
    }
    lowcost[beg]=0;
    for(int j=0;j<n;j++){
        int k=-1;
        int Min=INF;
        for(int i=0;i<n;i++)
            if(!vis[i]&&lowcost[i]<Min){
                Min=lowcost[i];
                k=i;
            }
        if(k==-1)break;
        vis[k]=true;
        for(int i=0;i<n;i++)
            if(!vis[i]&&lowcost[k]+cost[k][i]<lowcost[i]){
                lowcost[i]=lowcost[k]+cost[k][i];
                pre[i]=k;
            }
    }
}

int main(){
    return 0;
}
View Code

c2.Dijkstra算法+堆优化

技术分享
/*
Dijkstra算法+堆优化
使用优先队列优化,复杂度O(E log E)
使用优先队列优化Dijkstra算法
复杂度O(E log E)
注意对vector<Edge>E[MAXN]进行初始化后加边
*/
#include<iostream>
#include<stdio.h>
#include<vector>
#include<string.h>
#include<queue>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=1000010;
struct qnode{
    int v;
    int c;
    qnode(int _v=0,int _c=0):v(_v),c(_c){}
    bool operator <(const qnode &r)const{
        return c>r.c;
    }
};
struct Edge{
    int v,cost;
    Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
};
vector<Edge>E[MAXN];
bool vis[MAXN];
int dist[MAXN];
//点的编号从1开始
void Dijkstra(int n,int start){
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++)dist[i]=INF;
    priority_queue<qnode>que;
    while(!que.empty())que.pop();
    dist[start]=0;
    que.push(qnode(start,0));
    qnode tmp;
    while(!que.empty()){
        tmp=que.top();
        que.pop();
        int u=tmp.v;
        if(vis[u])continue;
        vis[u]=true;
        for(int i=0;i<E[u].size();i++){
            int v=E[tmp.v][i].v;
            int cost=E[u][i].cost;
            if(!vis[v]&&dist[v]>dist[u]+cost){
                dist[v]=dist[u]+cost;
                que.push(qnode(v,dist[v]));
            }
        }
    }
}
void addedge(int u,int v,int w){
    E[u].push_back(Edge(v,w));
}

int main(){

    return 0;
}
View Code

c3.单源最短路bellman_ford算法

技术分享
/*
单源最短路bellman_ford算法
单源最短khtkbellman_ford算法,复杂度O(VE)
可以处理负边权图。
可以判断是否存在负环回路。返回true,当且仅当图中不包含从源点可达的负权回路
vector<Edge>E;先E.clear()初始化,然后加入所有边
点的编号从1开始(从0开始简单修改就可以了)
*/
#include<iostream>
#include<stdio.h>
#include<vector>
using namespace std;

const int INF=0x3f3f3f3f;
const int MAXN=550;
int dist[MAXN];
struct Edge{
    int u,v;
    int cost;
    Edge(int _u=0,int _v=0,int _cost=0):u(_u),v(_v),cost(_cost){}
};
vector<Edge>E;
//点的编号从1开始
bool bellman_ford(int start,int n){
    for(int i=1;i<=n;i++)dist[i]=INF;
    dist[start]=0;
    //最多做n-1次
    for(int i=1;i<n;i++){
        bool flag=false;
        for(int j=0;j<E.size();j++){
            int u=E[j].u;
            int v=E[j].v;
            int cost=E[j].cost;
            if(dist[v]>dist[u]+cost){
                dist[v]=dist[u]+cost;
                flag=true;
            }
        }
        if(!flag)return true;//没有负环回路
    }
    for(int j=0;j<E.size();j++)
        if(dist[E[j].v]>dist[E[j].u]+E[j].cost)
            return false;//有负环回路
    return true;//没有负环回路
}

int main(){

    return 0;
}
View Code

c4.单源最短路SPFA

技术分享
/*
单源最短路SPFA
时间复杂度O(kE)
这个是队列实现,有时候改成栈实现会更加快,很容易修改
这个复杂度是不定的
*/
#include<iostream>
#include<stdio.h>
#include<vector>
#include<string.h>
#include<queue>
using namespace std;

const int MAXN=1010;
const int INF=0x3f3f3f3f;
struct Edge{
    int v;
    int cost;
    Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
};
vector<Edge>E[MAXN];
void addedge(int u,int v,int w){
    E[u].push_back(Edge(v,w));
}
bool vis[MAXN];//在队列标志
int cnt[MAXN];//每个点的入队列次数
int dist[MAXN];
bool SPFA(int start,int n){
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++)dist[i]=INF;
    vis[start]=true;
    dist[start]=0;
    queue<int>que;
    while(!que.empty())que.pop();
    que.push(start);
    memset(cnt,0,sizeof(cnt));
    cnt[start]=1;
    while(!que.empty()){
        int u=que.front();
        que.pop();
        vis[u]=false;
        for(int i=0;i<E[u].size();i++){
            int v=E[u][i].v;
            if(dist[v]>dist[u]+E[u][i].cost){
                dist[v]=dist[u]+E[u][i].cost;
                if(!vis[v]){
                    vis[v]=true;
                    que.push(v);
                    if(++cnt[v]>n)return false;
                    //cnt[i] 为入队列次数,用来判定是否存在负环回路
                }
            }
        }
    }
    return true;
}

int main(){

    return 0;
}
View Code

 

最短路径

标签:

原文地址:http://www.cnblogs.com/bofengyu/p/5365200.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!