本题是用Dijkstra算法求最短路径的第一题。使用了一个mark[]来实现已确定集合与未确定集合的区分,使用一个dist[]来存储目前的最短路径,使用newPoint存储上一趟选中的已确定结点。将Dijkstra算法用代码语言实现一遍即可。
需要注意的是,初始时需要将出发结点x作为newPoint并将x加入已确定集合来初始化。
debug过程:
①粗心将
for (i++;i<graph.graphSize;i++){
if (mark[i]==false&&dist[i]!=-1&&dist[i]<dist[minDistVex])
minDistVex=i;
}
newPoint=minDistVex;
mark[minDistVex]=true;
中的
newPoint=minDistVex;
mark[minDistVex]=true;
写到了for的里头。这样带来的问题是导致当进行Dijkstra的最后一趟时,for会直接被跳过一次都不执行,从而使这两句语句也一次不执行,于是便出现问题。
-
题目描述:
-
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
-
输入:
-
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。输入保证至少存在1条商店到赛场的路线。
当输入为两个0时,输入结束。
-
输出:
-
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间。
-
样例输入:
-
2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
-
样例输出:
-
3 2
#include <iostream>
#include <vector>
#include <iomanip>
#define MAXSIZE 200
using namespace std;
struct Edge{
int start,end;
double weight;
Edge(){
}
Edge(int start,int end,double weight){
this->start=start;
this->end=end;
this->weight=weight;
}
};
struct Vex{
int root;
Vex(){//initiate root
this->root=-1;
}
};
struct Graph{ //顶点下标从0开始
int graphSize;
vector<Edge> edge[MAXSIZE];
vector<Vex> vex;
int initGraph(int graphSize){
this->graphSize=graphSize;
for (int i=0;i<graphSize;i++)
edge[i].clear();
vex.clear();
}
};
int main(){
int n,m,x;
Graph graph;
int start,end,weight;
bool mark[MAXSIZE];
int dist[MAXSIZE];
int newPoint,minDistVex;
int temp;
while (cin>>n>>m,n||m){//n vexes ,m edges
//initiate
graph.initGraph(n);
newPoint=0;
for (int i=0;i<graph.graphSize;i++){
mark[i]=false;
dist[i]=65000;
}
mark[newPoint]=true;
dist[newPoint]=0;
//input edge
for (int i=0;i<m;i++){
cin>>start>>end>>weight;
start--;end--;
graph.edge[start].push_back(Edge(start,end,weight));
graph.edge[end].push_back(Edge(end,start,weight));
}
//process
for (int time=0;time<n-1;time++){//每趟循环找出x到一个结点的最短路径,共n-1趟
//遍历newPoint直接相邻的结点,修改其dist
for (int i=0;i<graph.edge[newPoint].size();i++){
temp=dist[newPoint]+graph.edge[newPoint][i].weight;
if (temp<dist[graph.edge[newPoint][i].end]) //if the new dist< the old dist
dist[graph.edge[newPoint][i].end]=temp;
}
//遍历dist,从mark为false的结点中找出其dist最小的结点,确定为新的newPoint,并加入x集合
int i;
for (i=0;i<graph.graphSize;i++){//initiate minDistVex
if (mark[i]==false){
minDistVex=i;
break;
}
}
for (i++;i<graph.graphSize;i++){
if (mark[i]==false&&dist[i]<dist[minDistVex])
minDistVex=i;
}
newPoint=minDistVex;
mark[minDistVex]=true;
}
//output
cout<<dist[n-1]<<endl;
}
return true;
}