#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
/*
Dijkstra算法,邻接矩阵形式,复杂度为O(n^2)
求出源beg到所有点的最短路径,
传入图的顶点数n和邻接矩阵cost[][]
返回各点的最短路径lowcost[],
路径pre[],pre[i]记录beg到i路径上的父节点,pre[beg]=-1
权值必须非负,下标0-n
*/
const int MAXN = 1010; //最大顶点数目
const int INF = 0x3f3f3f3f; //表示无穷
bool vis[MAXN]; //用于区分访问过/未访问过的顶点
int pre[MAXN]; //记录路径上i的父节点
void Dijkstra(int cost[][MAXN], int lowcost[], int n, int beg)
{
//第一步、初始化lowcost, vis, pre
for(int i=0; i<=n; i++)
{
lowcost[i]=INF;
vis[i]=false;
pre[i]=-1;
}
lowcost[beg]=0; //源到源为0
//第二步、每次从!vis集合中选出距离vis集合最短的顶点加入vis集合
//并更新!vis中的各顶点最短距离
for(int i=0; i<=n; i++)
{
//选顶点(首次选的总是源点)
int k=-1;
int min=INF;
for(int i=0; i<=n; i++)
{
if(!vis[i] && lowcost[i]<min)
{
min=lowcost[i];
k=i;
}
}
if(k==-1)break; //所有顶点都访问完,或无点可选,则退出
vis[k]=true; //标记该顶点加入vis集合
//更新!vis中的各顶点最短距离
for(int i=0; i<=n; i++)
{
if(!vis[i] && lowcost[i]>lowcost[k]+cost[k][i])
{
lowcost[i]=lowcost[k]+cost[k][i];
pre[i]=k; //记录父节点
}
}
}
}
int t,s,d;
int cost[MAXN][MAXN];
int lowcost[MAXN];
int want[MAXN];
int num; //记录最大顶点个数
int main()
{
while(scanf("%d %d %d",&t,&s,&d)!=EOF)
{
//输入邻接矩阵
memset(cost,0x3f,sizeof(cost)); //清空
int x,y,z;
for(int i=0; i<t; i++)
{
cin>>x>>y>>z;
num=max(max(num,x),y); //记录最大顶点个数
if(z<cost[x][y])
cost[x][y]=cost[y][x]=z;
}
//输入相邻城市
for(int i=0; i<s; i++)
{
cin>>x;
cost[x][0]=cost[0][x]=0; //权值为0
}
//输入想去城市
for(int i=0; i<d; i++)
cin>>want[i];
//调用算法求出单源最短距离
Dijkstra(cost, lowcost, num, 0);
//计算最短距离并输出
int mind=INF;
for(int i=0; i<d; i++)
{
mind=min(mind, lowcost[want[i]]);
}
cout<<mind<<endl;
}
return 0;
}
【杭电100题】【Dijkstra】2066 一个人的旅行
猜你喜欢
转载自blog.csdn.net/qq_41727666/article/details/88314269
今日推荐
周排行