-
定义了一个图的数据结构,包括邻接矩阵a和b,顶点数vex,最小值mins和边数arm。其中,邻接矩阵a用于存储边的权重(距离),邻接矩阵b用于存储边的耗时。
-
创建图的函数creatgp,输入图的顶点数、边数和最小值,然后初始化邻接矩阵a和b,将邻接矩阵a的对角线元素设为0,表示顶点到自身的距离为0,其他元素设为最大值maxxs,表示顶点之间没有直接连接;将邻接矩阵b的元素设为最大值timersmax,表示顶点之间没有直接连接。然后根据输入的边的信息,更新邻接矩阵a和b。
-
打印路径的函数print,输入图、距离数组dist、路径数组path、标记数组s和时间数组timer,输出从起点到终点的最短路径及其耗时和距离。
-
实现Dijkstra算法的函数dj,输入图,计算从起点到各个顶点的最短距离、最短路径和最短耗时,然后调用print函数输出结果。
-
main函数,创建图p,调用creatgp函数创建图,然后调用dj函数求解最短路径问题。#include<bits/stdc++.h>
-
using namespace std;
-
#define max 1001
#define maxxs 10008660
#define timersmax 1000777
typedef struct{
int a[max][max];//代表时间图
int b[max][max];//定义图 路程图
int vex;
int mins;
int arm;
}*graph,Graph;
void creatgp(graph &p)//创建
{
if(p==NULL)
{
p=new Graph;
cin>>p->vex>>p->arm>>p->mins;
}
for(int i=0;i<max;i++)
{
for(int j=0;j<max;j++)
{
p->a[i][j]=maxxs;
p->b[i][j]=timersmax;
if(i==j)
p->a[i][j]=0;
}
}
for(int i=1;i<=p->arm;i++)
{
int x,y,time,dist;
cin>>x>>y>>time>>dist;
p->a[x][y]=dist;
p->a[y][x]=dist;
p->b[x][y]=time;
p->b[y][x]=time;
}
}
void print(graph &p,int *dist,int *path,int *s,int *timer)
{
int apath[max];
int k=p->mins;
int d=0;
apath[d]=k;
cout<<timer[k]<<" "<<dist[k]<<" ";
int times=0;
k=path[k];
while(k!=1)
{
d++;
apath[d]=k;
k=path[k];
}
cout<<"1";
for(;d>=0;d--)
{
cout<<"->"<<apath[d];
}
}
void dj(graph &p)//注意 这道题的时间权重大于路程 所以遍历时先比较时间 时间相等时比较路程
{
int dist[max];
int s[max]={0};
int path[max];
int timer[max];
for(int i=1;i<=p->vex;i++)
{
if(p->a[1][i]!=0&&p->a[1][i]<maxxs)//初始并查集
path[i]=1;
else path[i]=0;
}
for(int i=1;i<=p->vex;i++)
{
dist[i]=p->a[1][i];
if(p->b[1][i]!=0&&p->b[1][i]<timersmax)//初始化 时间数组和路程数组
timer[i]=p->b[1][i];
else{
timer[i]=timersmax;
}
}
s[1]=-1;
for(int i=2;i<=p->vex;i++)
{
int min=maxxs;
int k = 1;
int timemin=timersmax;
for(int j=1;j<=p->vex;j++)
{
if(s[j]!=-1)
{
if(timer[j]!=0&&timemin>timer[j])//这里先比较时间
{
k=j;
timemin=timer[j];
min=dist[j];
}
else if(timer[j]!=0&&timemin==timer[j])//时间相等时比较路程
{
if(min>dist[j])
{
k=j;
min = dist[j];
}
}
}
}
s[k]=-1;
for(int j=1;j<=p->vex;j++)
{
if(s[j]!=-1)
{
if(timer[k]+p->b[k][j]<timer[j])//跟新数据如上
{
timer[j]=timer[k]+p->b[k][j];
path[j]=k;
dist[j]=dist[k]+p->a[k][j];
}
else if(timer[k]+p->b[k][j]==timer[j])
{
if(dist[j]>dist[k]+p->a[k][j])
{
path[j]=k;
dist[j]=dist[k]+p->a[k][j];
}
}
}
}
}
print(p,dist,path,s,timer);
}
int main()
{
graph p =NULL;
creatgp(p);
dj(p);
return 0;
}
春天阳光灿烂,小宋突然心血来潮想骑自行车去学校外面玩,但是到达目的地的路线不止一条,他想尽快的到达目的地,又能不需要骑太远的路, 你能帮助他吗?
输入格式:
输入包含一个测试数据,第一行有三个整数n(2 <= n <= 1000),途中可能经过的地点的个数,地点编号1~n;m(1 <= m <= 10000),为路径的条数;d(2 <= d <= n),目的地编号;其中学校为起点,默认为1。接下来m行: x y time dist , x y表示地点x,y是可以相互到达的,time,dist分别表示x到y或y到x的时间,距离。
输出格式:
按如下格式输出“花费的时间+空格+要骑的距离+空格+从学校到达目的地的路径”,路径中的两个地点之间以箭头(->)分隔。(具体见输出样例)
输入样例:
在这里给出一组输入。例如:
7 8 7
1 2 1 1
1 3 1 1
2 4 1 2
3 4 1 1
4 5 1 2
4 6 1 1
5 7 1 1
6 7 2 1
输出输出
4 5 1->3->4->5->7