前言
Dijkstra算法能够有效地计算出源点到其余所有顶点的最短路径。
该算法在运行过程中将顶点集合V分成两个集合S和T。
(1)S:已确定的顶点集合,初始只含源点s。
(2)T=V-S:尚未确定的顶点集合。
算法反复从T中选择当前到源点s最近的顶点u,将u加入集合S,然后对所有从u发出的边进行松弛操作。
【题目1:畅通工程续】
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
【输入】
第一行:N(0
接下来M行,A,B,X,表示A—B(X)的双向道路。
再接下来的下一行:S(起点),T(终点)。
【输出】
输出最短需要行走的距离。若不存在则输出-1;
【样例输入】
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2
【样例输出】
2
-1
【代码】
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=200;
const int INF=INT_MAX;//无穷大设为很大的数
struct Edge{
int to;//终点
int length;
Edge(int t,int l){
to=t;
length=l;
}
};
struct Point{
int number;
int distance;
Point(int n,int d)
{
number=n;
distance=d;
}
bool operator<(const Point&p)const{
return distance>p.distance;//距离小的优先级高
}
};
vector graph[MAXN];//邻接表实现的图
int dis[MAXN];//源点到各点距离
void Dijkstra(int s){
priority_queue myPriorityQueue;
dis[s]=0;
myPriorityQueue.push(Point(s,dis[s]));
while(!myPriorityQueue.empty()){
int u=myPriorityQueue.top().number;//离源点最近的点
myPriorityQueue.pop();
for(int i=0;idis[u]+d){
dis[v]=dis[u]+d;
myPriorityQueue.push(Point(v,dis[v]));
}
}
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
memset(graph,0,sizeof(graph));//图初始化
fill(dis,dis+n,INF);//距离初始化为无穷
while(m--)
{
int from,to,length;
cin>>from>>to>>length;
graph[from].push_back(Edge(to,length));
graph[to].push_back(Edge(from,length));
}
int s,t;
cin>>s>>t;
Dijkstra(s);
if(dis[t]==INF)
dis[t]=-1;
cout<
题目2:最短路径问题
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入描述:
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1
输出描述:
输出 一行有两个数, 最短距离及其花费。
示例1
输入
3 2
1 2 5 6
2 3 4 5
1 3
0 0
输出
9 11
注意
本题不仅需要求起点到终点的最短距离,还需要在有多条最短路径时,选取花费最少的那一条,只需更改Dijstra算法中的松弛操作:新的路径若在距离上优于之前的路径,或者新的路径在距离上等于之前的路径,但花费要优于之前的路径,则更新路径和花费。
代码
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=1001;
const int INF=INT_MAX;
struct Edge{
int to;
int length;
int price;
Edge(int t,int l,int p)
{
to=t;
length=l;
price=p;
}
};
struct Point{
int number;
int distance;
Point(int n,int d)
{
number=n;
distance=d;
}
bool operator<(const Point& p)const{
return distance>p.distance;//距离小的优先级高
}
};
vector graph[MAXN];
int dis[MAXN];
int cost[MAXN];
void Dijkstra(int s)
{
priority_queue myPriorityQueue;
dis[s]=0;
cost[s]=0;
myPriorityQueue.push(Point(s,dis[s]));
while(!myPriorityQueue.empty())
{
int u=myPriorityQueue.top().number;
myPriorityQueue.pop();
for(int i=0;icost[u]+p)||dis[v]>dis[u]+l)
{
dis[v]=dis[u]+l;
cost[v]=cost[u]+p;
myPriorityQueue.push(Point(v,dis[v]));
}
}
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
memset(graph,0,sizeof(graph));
fill(dis,dis+n+1,INF);
fill(cost,cost+1,INF);
while(m--)
{
int from,to,length,price;
cin>>from>>to>>length>>price;
graph[from].push_back(Edge(to,length,price));
graph[to].push_back(Edge(from,length,price));
}
int s,t;
cin>>s>>t;
Dijkstra(s);
cout<