2018-5-1
今天抽时间看了最短路的几种算法:
这道题目用的是Dijkstra算法,算法的主要思想是按照路径长度递增的次序产生最短路径。
对于这个题目而言,需要注意的是:
1)赋值是双向的,比如说a,b之间有一条要花费time时间的路,那么我们需要将x[a][b]与x[b][a]都赋值为time。
2)有重边:对于这种情况我们需要取最小的边。
3)多源转换为单源:其实也就等同于0点到所有的起始点的距离为0,可以转换成只要求出以0为起始点的到所有目标点的距离的最小值。
#include<iostream>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1000;
bool vis[N+1];
int target[N+1];
int dis[N+1],x[N+1][N+1],start[N+1];
int t,s,d,n,res;
void dijkstra(){
int i,j,min_dis,min_point;
for (i=1;i<=n;i++) dis[i]=inf;
vis[0]=true;
for (i=0;i<=n;i++){
dis[i]=x[0][i];
}
for (i=0;i<n;i++){
min_dis=inf;
min_point=0;
for (j=1;j<=n;j++){
if (!vis[j]&&dis[j]<min_dis){
min_dis=dis[j];
min_point=j;
}
}
vis[min_point]=true;
for (j=1;j<=n;j++){
if (!vis[j]&&(x[min_point][j]+min_dis<dis[j])){
dis[j]=x[min_point][j]+min_dis;
}
}
}
}
int main(){
int i,j,a,b,tim;
while (cin>>t>>s>>d){
for (i=0;i<=N;i++){
for (j=0;j<=N;j++){
x[i][j]=inf;
}
}
memset(vis,false,sizeof(vis));
n=0;res=inf;
for (i=1;i<=t;i++){
cin>>a>>b>>tim;
x[a][b]=x[a][b]<tim?x[a][b]:tim;
x[b][a]=x[a][b]<tim?x[a][b]:tim;
n=max(max(a,b),n);
}
for (i=1;i<=s;i++){
cin>>start[i];
x[0][start[i]]=0;
x[start[i]][0]=0;
}
for (i=1;i<=d;i++){
cin>>target[i];
}
dijkstra();
for (i=1;i<=d;i++){
res=min(res,dis[target[i]]);
}
cout<<res<<endl;
}
return 0;
}