差不多算是第一个了解的算法,主要是做pat甲级时要用,依照的是《数据结构与算法分析》这本书;
之前本来就想用lis作为链表,但是貌似只能存一个数据,存不了权,只能自己建链表做了,最近看到pair,也不知道这么用对不对
试着写写,之后等再深入了解c++后再回来看看吧。
题目 : https://www.patest.cn/contests/pat-a-practise/1003
/*dijkstra算法求最短路径 邻接表表示图**/
#include <iostream>
#include <list>
#include <utility>
#include <iterator>
#define NotAVertex (-1)
#define INF (1<<30)
#define MAX 500
using namespace std;
static int numvertex, start;
typedef struct TableEntry
{
list< pair<int,int> > mylist;
bool known;
int dist;
int path;
}adjacency_list;
adjacency_list graph[MAX];
void graph_init()
{
int v, w;
int i;
for(i=1; i<=numvertex; i++)
{
graph[i].dist = INF;
graph[i].known = false;
graph[i].path = NotAVertex;
}
graph[start].dist = 0;
for(i=1; i<=numvertex; i++)
{
cout << "输入顶点" << i << "的邻接点及其权值" << endl;
//"windows下输入回车后输入ctrl+z linux下输入ctrl+d结束输入"
while(cin >> v >> w)
{
graph[i].mylist.push_back(make_pair(v, w));//fisrt表示顶点,second表示权;
}
cin.clear();
}
}
void dijkstra()
{
int i, j, mindist, key;
list< pair<int, int> >::iterator it;
for(i=1; i<=numvertex; i++)
{
mindist = INF;
for(j=1; j<=numvertex; j++)
{
if(!graph[j].known && graph[j].dist<mindist)
{
mindist = graph[j].dist;
key = j;
}
}
graph[key].known = true;
for(it=graph[key].mylist.begin(); it!=graph[key].mylist.end(); it++)
{
if(!graph[it->first].known)
{
if(it->second+mindist < graph[it->first].dist)
{
graph[it->first].dist = it->second+mindist;
graph[it->first].path = key;
}
}
}
}
}
void print_path(int end_vertex)
{
if(graph[end_vertex].path != NotAVertex)
{
print_path(graph[end_vertex].path);
cout << "到";
}
cout << end_vertex;
}
int main()
{
cout << "输入顶点的数量和所求最短路径的起点" << endl;
cin >> numvertex >> start;
graph_init();
dijkstra();
for(int i=1; i<=numvertex; i++)
{
cout << "地点" << start << "到地点" << i << "的最短路径路线为:" << endl;
print_path(i);
cout << endl << "最短路径长为" << graph[i].dist << endl << endl;
}
return 0;
}
附上之前写的
/*dijkstra算法求最短路径 邻接表表示图**/
#include <iostream>
#define NotAVertex (-1)
#define INF (1<<30)
#define MAX 500
using namespace std;
static int numvertex, start;
typedef struct NODE
{
int adjvex;
int weight;
struct NODE *next;
}Node;
typedef struct TableEntry
{
Node *header;
bool known;
int dist;
int path;
}adjacency_list;
adjacency_list graph[MAX];
void graph_init()
{
int v, w;
int i;
Node *p;
for(i=1; i<=numvertex; i++)//初始化图数据
{
graph[i].dist = INF;
graph[i].known = false;
graph[i].path = NotAVertex;
graph[i].header = NULL;
}
graph[start].dist = 0;//起始节点最短距离为0;
for(i=1; i<=numvertex; i++)
{
cout << "输入顶点" << i << "的邻接点及其权值" << endl;
//"windows下输入回车后输入ctrl+z linux下输入ctrl+d结束输入"
while(cin >> v >> w)//头插法创建链表
{
p = new Node;
p->adjvex = v;
p->weight = w;
p->next = graph[i].header;
graph[i].header = p;
}
cin.clear();
}
}
void dijkstra()
{
int i, j, mindist, key;
Node *p = NULL;
for(i=1; i<=numvertex; i++)
{
mindist = INF;
for(j=1; j<=numvertex; j++)//求当前未知的最短距离点
{
if(!graph[j].known && graph[j].dist<mindist)
{
mindist = graph[j].dist;
key = j;
}
}
graph[key].known = true;//标记已知
p = graph[key].header;//指向该点内链表表头
while(p != NULL)
{
if(!graph[p->adjvex].known)
{
if(p->weight+mindist < graph[p->adjvex].dist)//如果key点邻接点的已知最小距离比key点到邻接点距离加上key到基点最短距离要大则更新
{
graph[p->adjvex].dist = p->weight+mindist;
graph[p->adjvex].path = key;//标记该邻接点最短距离的前位点为key点
}
}
p = p->next;
}
}
}
void print_path(int end_vertex)
{
if(graph[end_vertex].path != NotAVertex)
{
print_path(graph[end_vertex].path);//递归遍历前位点,输入路径
cout << "到";
}
cout << end_vertex;
}
int main()
{
cout << "输入顶点的数量和所求最短路径的起点" << endl;
cin >> numvertex >> start;
graph_init();
dijkstra();
for(int i=1; i<=numvertex; i++)
{
cout << "地点" << start << "到地点" << i << "的最短路径路线为:" << endl;
print_path(i);
cout << endl << "最短路径长为" << graph[i].dist << endl << endl;
}
return 0;
}