原题链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2066
思路:这道题目就是最短路径问题上变化一下,根据题意,出发点不止一个,目的地也不止一个,求的是从某一个出发点到某一个目的点,最近的距离,
思路:这道题目就是最短路径问题上变化一下,根据题意,出发点不止一个,目的地也不止一个,求的是从某一个出发点到某一个目的点,最近的距离,
注意,只要求其中一个即可(题目描述是到某一个喜欢的城市的最短时间)。最直观的想法就是任意两个都求,最后比较,很耗时间,会超时,
因此就是加入超级起点(用0表示)以及超级终点k(用最大城市数字+1表示),这样,只需要求一次(0,k)最短路径即可,具体看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int Max=0x3f3f3f;
const int N=1005;
int maps[N][N];
int dis[N];
bool vis[N];
void init()
{
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
maps[i][j]=(i==j?0:Max);
}
void Dijkstra(int st,int ed)
{
int i,j;
memset(vis,0,sizeof(vis));
for(i=0;i<=ed;i++)
{
dis[i]=(i==st?0:Max);
}
dis[st]=0;
int temp,k;
for(i=0;i<=ed;i++){
temp=Max;
for(j=0;j<=ed;j++)
if(!vis[j] && dis[j]<temp)
temp=dis[k=j];
vis[k]=1;
// if(k==ed || temp==Max) return;
for(j=0;j<=ed;j++)
{
if(!vis[j]&&dis[j]>dis[k]+maps[k][j])
dis[j]=maps[k][j]+dis[k];
}
}
return;
}
int main()
{
int m,n,i,j,k;
int s,d;
while(~scanf("%d%d%d",&n,&s,&d)){
init();
int x,y,w;
k=0;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&x,&y,&w);
maps[x][y]=maps[y][x]=min(w,maps[x][y]);
k=max(x,max(k,y));
}
k++;//加入两个超级汇点,0和k(最大值加1)
for(i=0;i<s;i++)
{
scanf("%d",&j);
maps[0][j]=0;
maps[j][0]=0;
}
for(i=0;i<d;i++)
{
scanf("%d",&j);
maps[j][k]=0;
maps[k][j]=0;
}
Dijkstra(0,k);
printf("%d\n",dis[k]);
}
return 0;
}