hdu2066 dijkstra多源点多终点求最短路径

dijkstra算法的思路:

(1)找到最短距离已经确定的顶点,从它出发更新相邻顶点的最短距离

(2)此后不再关心(1)中最短距离已经确定的顶点

最开始时只有起点的最短距离是确定的,而在未使用过的顶点中,距离d[i]最小的顶点就是最短距离已经确定的顶点,在不存在负边的情况下d[i]不会在之后的更新中变小。  存在负边则无法使用dijkstra

使用优先队列实现:

#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 1000+50;
const int INF=100000;

class HeapNode{
    public:
    int d,u;
    bool operator <(const HeapNode & rhs) const{
    return d>rhs.d;
    }
};

class Edge {
    public:
    int to,dist;
    Edge(int to=0,int dist=0):to(to),dist(dist){}
};

vector<Edge>G[maxn];
int d[maxn];
bool done[maxn];

void dijkstra(int s){
    priority_queue<HeapNode> Q;
    for(int i=0;i<maxn;i++)d[i]=INF;
    d[s]=0;
    memset(done,0,sizeof(done));
    Q.push((HeapNode){0,s});
    while(!Q.empty()){
     HeapNode x=Q.top();Q.pop();
     int u=x.u;
     if(done[u])continue;
     done[u]=true;
     for(int i=0;i<G[u].size();i++){
        Edge& e=G[u][i];
        if(d[e.to]>d[u]+e.dist){
            d[e.to]=d[u]+e.dist;
            Q.push((HeapNode){d[e.to],e.to});
        }
      }
    }
}

int main(){
    //freopen("datain.txt","r",stdin);
    int T,S,D;
    while(~scanf("%d%d%d",&T,&S,&D)){
        int ans=INF;
        for(int i=0;i<maxn;i++)
            G[i].clear();
        for(int i=0;i<T;i++){
            int from,to,dist;
            scanf("%d%d%d",&from,&to,&dist);
            G[from].push_back(Edge(to,dist));
            G[to].push_back(Edge(from,dist));
        }
        for(int i=0;i<S;i++){
            int source;
            scanf("%d",&source);
            G[0].push_back(Edge(source,0));
            G[source].push_back(Edge(0,0));
        }
        int dest[maxn];
        for(int i=0;i<D;i++)
            scanf("%d",&dest[i]);
        dijkstra(0);
        for(int i=0;i<D;i++)
            ans=min(ans,d[dest[i]]);
        printf("%d\n",ans);
    }
}

 

 

而图中存在负边的情况,则需要使用Bellman-Ford或者Floyd-Warshall算法

Bellman-Ford:

#include<cstdio>
#include <iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#define INF 1000000
const int maxn = 1000 + 5;
using namespace std;
int d[maxn];//最短距离
int V, E;//顶点数 边数
struct edge{
	int from, to, cost;
}edges[maxn];
void shortest_path(int s) {
	for (int i = 0;i < V;i++) d[i] = INF;
	d[s] = 0;
	while (true) {
		bool update = false;
		for (int i = 0;i < E;i++) {
			edge e = edges[i];
			if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
				d[e.to] = d[e.from] + e.cost;
				update = true;
			}
		}
		if (!update)break;
	}
}
bool find_negative_loop() {
	memset(d, 0, sizeof(d));
	for (int i = 0;i < V;i++) {
		for (int j = 0;j < E;j++) {
			edge e = edges[j];
			if (d[e.to] > d[e.from] + e.cost) {
				d[e.to] = d[e.from] + e.cost;
				if (i == V - 1)return true;//第V次仍然更新了
			}
		}
	}return false;
}

 

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/hanker99/article/details/84191189
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞