传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2066
【分析】Dijkstra的模板题目(水题),由于刚学,然后虽然自己AC了,但是在想去的城市中找最短路径的时候我用了暴力,我看到了一个更好的。
【我的代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int map[1000+10][1000+10];
int dist[1000+10];
int path[1000+10];
int s[1000+10];
const int M=0x3f3f3f3f;
int big;
int city[1000+10];
void Dijkstra(int v);
int main()
{
int t,s,d;
while(scanf("%d%d%d",&t,&s,&d)!=EOF)
{
for(int i=0;i<1000+10;i++)
{
for(int j=0;j<1000+10;j++)
{
if(i==j)
map[i][j]=0;
else
map[i][j]=M;
}
}
int a,b,c;
while(t--)
{
scanf("%d%d%d",&a,&b,&c);
if(c<map[a][b])
map[a][b]=map[b][a]=c;
big=max(big,max(a,b)); //主要为了知道这个map的多少阶的
}
memset(city,M,sizeof(city));
int ss[1000+10];
for(int i=1;i<=s;i++)
scanf("%d",&ss[i]);
for(int i=1;i<=d;i++)
scanf("%d",&city[i]);
int flag=M; //去最近的城市的路为M。
for(int j=1;j<=s;j++)
{
Dijkstra(ss[j]); //在每一次调用函数的时候dist都不同
for(int i=1;i<=d;i++) //用暴力找到最小的。
flag=min(flag,dist[city[i]]);
}
printf("%d\n",flag);
}
}
void Dijkstra(int v)
{
for(int i=1;i<=big;i++)
{
dist[i]=map[v][i];
s[i]=0;
}
s[v]=1;
dist[v]=0;
for(int i=1;i<big;i++)
{
int min=M;
int k=v;
for(int j=1;j<=big;j++)
{
if(!s[j] && dist[j]<min)
{
min=dist[j];
k=j;
}
}
s[k]=1;
for(int j=1;j<=big;j++)
{
if(!s[j] && map[k][j]<M && dist[j]>dist[k]+map[k][j])
{
dist[j]=map[k][j]+dist[k];
}
}
}
}
【别人的代码】
将草儿的家看做点0,从草儿家到相邻镇的花费的时间为0
那么我们就只需要求草儿家到各个目的地的最短路即可,一次Dijkstra便可解决
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int inf = 1<<30;
int T,S,D,n;
int map[1111][1111];
int vis[1111],cast[1111];
int s[1111],e[1111];
void Dijkstra()
{
int i,j,minn,pos;
memset(vis,0,sizeof(vis));
vis[0] = 1;
for(i = 0; i<=n; i++)
cast[i] = map[0][i];
for(i = 1; i<=n; i++)
{
minn = inf;
for(j = 1; j<=n; j++)
{
if(cast[j]<minn && !vis[j])
{
pos = j;
minn = cast[j];
}
}
vis[pos] = 1;
for(j = 1; j<=n; j++)
{
if(cast[pos]+map[pos][j]<cast[j] && !vis[j])
cast[j] = cast[pos]+map[pos][j];
}
}
}
int main()
{
int i,j,x,y,z,start,end;
while(~scanf("%d%d%d",&T,&S,&D))
{
n = 0;
for(i = 0; i<1111; i++)
{
for(j = 0; j<1111; j++)
map[i][j] = inf;
map[i][i] = 0;
}
while(T--)
{
scanf("%d%d%d",&x,&y,&z);
n = max(max(n,x),y);
if(z<map[x][y])
map[x][y] = map[y][x] = z;
}
int minn = inf;
for(i = 0; i<S; i++) //关键的一步
{
scanf("%d",&s[i]);
map[0][s[i]] = map[s[i]][0] = 0;
}
for(i = 0; i<D; i++)
scanf("%d",&e[i]);
Dijkstra(); //一次dijkstra()
for(i = 0; i<D; i++)
minn = min(minn,cast[e[i]]);
printf("%d\n",minn);
}
return 0;
}