赞
踩
Dijkstra算法能够有效地计算出源点到其余所有顶点的最短路径。
该算法在运行过程中将顶点集合V分成两个集合S和T。
(1)S:已确定的顶点集合,初始只含源点s。
(2)T=V-S:尚未确定的顶点集合。
算法反复从T中选择当前到源点s最近的顶点u,将u加入集合S,然后对所有从u发出的边进行松弛操作。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
第一行:N(0<N<200),M(0<M<1000),分别代表城镇数和已修道路数。
接下来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<iostream>
- #include<cstdio>
- #include<vector>
- #include<cstring>
- #include<queue>
- #include<climits>
- 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<Edge> graph[MAXN];//邻接表实现的图
- int dis[MAXN];//源点到各点距离
-
- void Dijkstra(int s){
- priority_queue<Point> myPriorityQueue;
- dis[s]=0;
- myPriorityQueue.push(Point(s,dis[s]));
- while(!myPriorityQueue.empty()){
- int u=myPriorityQueue.top().number;//离源点最近的点
- myPriorityQueue.pop();
- for(int i=0;i<graph[u].size();i++)
- {
- int v=graph[u][i].to;
- int d=graph[u][i].length;
- if(dis[v]>dis[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<<dis[t]<<endl;
- }
- return 0;
- }
给你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<n<=1000, 0<m<100000, s != t)
输出 一行有两个数, 最短距离及其花费。
示例1
- 3 2
- 1 2 5 6
- 2 3 4 5
- 1 3
- 0 0
9 11
本题不仅需要求起点到终点的最短距离,还需要在有多条最短路径时,选取花费最少的那一条,只需更改Dijstra算法中的松弛操作:新的路径若在距离上优于之前的路径,或者新的路径在距离上等于之前的路径,但花费要优于之前的路径,则更新路径和花费。
- #include<iostream>
- #include<cstdio>
- #include<vector>
- #include<cstring>
- #include<queue>
- #include<climits>
-
- 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<Edge> graph[MAXN];
- int dis[MAXN];
- int cost[MAXN];
- void Dijkstra(int s)
- {
- priority_queue<Point> 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;i<graph[u].size();i++)
- {
- int v=graph[u][i].to;
- int l=graph[u][i].length;
- int p=graph[u][i].price;
- if((dis[v]==dis[u]+l && cost[v]>cost[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<<dis[t]<<" "<<cost[t]<<endl;
- }
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。