1.题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2680
2.思路 :
这道题目是多个起点,一个终点,属于有向单源最短路问题。可以假设一个虚拟的起点,然后将虚拟起点到没有起点的距离设为0,这样就可以用dijkstra反向建图。
3.参考代码:
#include <stdio.h>
#include <string.h>
#define inf 0xffff
int n,m,s;
int edge[1100][1100]; ///图的邻接矩阵
int dis[1100]; ///存放距离的
int vis[1100]; ///标记是否访问过
void dijkstra(int v){ ///dijkstra算法
int i,j; ///循环变量
int k=0; ///标记,一定要记得先赋初始值为0
memset(vis,0,sizeof(vis)); ///初始化为都0,表示都没有访问过
for(i=1;i<=n;i++)
dis[i]=edge[v][i]; ///
vis[v]=1; ///标记起点为已访问过的
dis[v]=0; ///本身到本身的距离为0
for(i=1;i<=n;i++)
{
int min=inf;
for(j=1;j<=n;j++) ///遍历所有的点
{
if(dis[j]<min && !vis[j])
{
min=dis[j];
k=j;
}
}
if(min==inf) ///如果没有找到最小值,就退出
break;
vis[k]=1; ///标记已访问过
for(j=1;j<=n;j++) ///遍历所有的点
{
if(dis[j]>dis[k]+edge[k][j] && !vis[j])
dis[j]=dis[k]+edge[k][j];
}
}
if(dis[s]==inf)
printf("-1\n");
else
printf("%d\n",dis[s]);
}
int main()
{
int i,j; ///循环变量
int t,r;
int u,v,w; ///两个站点,以及它们之间的距离
while(~scanf("%d %d %d",&n,&m,&s))
{
for(i=0;i<=n;i++) ///注意这里的下标是从0开始的,从1不行
{
for(j=0;j<=n;j++) ///注意这里的下标是从0开始的,从1不行
{
if(i==j)
edge[i][j]=0;
else
edge[i][j]=edge[j][i]=inf;
}
}
//memset(edge,inf,sizeof(edge)); ///初始化不能这样做,否则得不到正确答案
while(m--)
{
scanf("%d %d %d",&u,&v,&w);
if(edge[u][v]>w) ///不要忘记消除重边的情况
edge[u][v]=w;
///edge[u][v]=edge[v][u]=w; ///不能这么写,不然会WA
}
scanf("%d",&t);
while(t--)
{
scanf("%d",&r);
edge[0][r]=0; ///所设的虚拟起点到没有顶点的距离都为0
}
dijkstra(0); ///从所设的虚拟起点开始
}
return 0;
}