Date: 2019-9-2
Author: ZLR
Problem: HDU-2544
Degree: ※
Algorithm: Dijkstra
单源含义:从这个点出发到每个点的最优路径
思路:
两个一维数组:
第一个数组表示已选定的最优点
第二个数组表示该点是否使用过
一个二维数组:
表示两点之间的距离
设你所在的顶点为1 则dis[1]=0;
fill(dis,dis+V,INF);dis[1]=0;自己到自己花费0
下一步活动找寻离自己距离最短的点(无限循环)
(邻接点当中距离最小的点)并且记录它的位置
如果每个点都找寻过了,就退出无限循环
在每一次找到该点后,便利所有不是已经选定的点,看看这些点与该点有没有通路,如果有通路,看看是自身到原点近,还是绕个弯离远点近。
例如 7->4: 5
4->1: 1
7->1: 8
7->4->1 :6
7->1 :8
第一步操作就是1->1 dis[1]=0;used[1]=1;
第二步 选4这个点,dis[4]=1; used[4]=1;
第三步 该选7,但是7这个点要怎么走呢?直接到1也有路,7->4,然后4->1也有路
看来我们只需要比较这两条路,选择的最优的则变成dis[7],显然为6
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<string>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 105
using namespace std;
int tu[maxn][maxn],dis[maxn],used[maxn];
int V,E;
int dijkstra()
{ fill(dis+1,dis+1+V,INF);dis[1]=0;memset(used,0,sizeof used);
while(true)
{
int pos=-1;
int minn=INF;
for(int j=1;j<=V;j++){
if(!used[j]&&minn>dis[j])
{
pos=j;
minn=dis[j];
}
}
if(pos==-1) break;
used[pos]=1;
for(int j=1;j<=V;j++){
if(!used[j])
dis[j]=min(dis[j],dis[pos]+tu[pos][j]);
}
}
return dis[V];
}
int main(){
int a,b,c;
while(scanf("%d %d",&V,&E),V||E){
memset(tu,INF,sizeof tu);
for(int i=0;i<E;i++){scanf("%d %d %d",&a,&b,&c);
if(tu[a][b]>c) tu[a][b]=tu[b][a]=c;
}
cout<<dijkstra()<<endl;
}
return 0;}