解题思路:说解题思路还谈不上,这是我的第一题图论算法AC,借鉴了这位大佬的解题思路:点击打开链接,勉勉强强写出来了,这种题难点可能是建图的时候吧,核心算法那边边算边松弛利用了贪心的思想,在输入邻接矩阵边的时候利用一个xymax来得到一张图的最大规模,从而在dijkstra中减少运算时间。本题由于一开始有好几个相邻城市,相当于第一次松弛到起点距离把这些点的情况(即:image[0][i]更新到dis中,这样在dijkstra就一定会从这些相邻的点先找)。
AC代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<string>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1005;
int T,S,D,xymax;
bool used[maxn];
int image[maxn][maxn],dis[maxn],book[maxn];
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a>b?b:a;
}
void dijkstra(int x)
{
fill(used+1,used+xymax+1,false);
int i;
for(i=0;i<=xymax;i++)
dis[i]=image[0][i];
used[x]=true; //可以省略 自己肯定是不能再走了
int u,v;
//dijkstra核心算法
while(1)
{
u=-1;
for(v=1;v<=xymax;v++)
if(!used[v] && (u==-1 || dis[u]>dis[v])) u=v;
if(u==-1)
break;
used[u]=true;
for(v=1;v<=xymax;v++) //松弛边
if(dis[v]>dis[u]+image[u][v])
dis[v]=dis[u]+image[u][v];
}
return ;
}
void init()
{
int i,j;
for(i=0;i<maxn;i++)
for(j=0;j<maxn;j++)
if(i==j) image[i][j]=0;
else image[i][j]=inf;
int cost,t1,t2,city;
xymax=-1;
for(i=0;i<T;i++)
{
scanf("%d%d%d",&t1,&t2,&cost);
xymax=max(max(t1,t2),xymax);
if(cost<image[t1][t2])
image[t1][t2]=image[t2][t1]=cost;
}
for(i=0;i<S;i++)
{
scanf("%d",&city); //把自己的城市用0表示,相邻城市的临接矩阵上的值要更新
image[0][city]=image[city][0]=0;
}
for(i=0;i<D;i++)
scanf("%d",&book[i]);
return ;
}
int main()
{
int Min,i;
while(~scanf("%d%d%d",&T,&S,&D))
{
init();
dijkstra(0);
Min=inf;
for(i=0;i<D;i++)
Min=min(Min,dis[book[i]]);
cout<<Min<<endl;
}
return 0;
}