http://acm.hdu.edu.cn/showproblem.php?pid=2544
#pragma warning (disable:4786)
#include<iostream>
#include<vector>
using namespace std;
#define INF 0x3F3F3F3F
struct Edge{
int v;
int dis;
};
int n,m;
int dist[102]; //最短路径数组
int visit[102]; //标记节点是否已访问
int dp[102]; //dp[i]=j表示节点i在最小堆中的位置为j
int vdp[102]; //vdp[i]=j表示在最小堆中位置i的是节点jint heap[102];
int heap[102]; //存储最短路径的最小堆
int heap_num; //最小堆的size
vector<Edge> edge[102]; //邻接表存储
//自顶向下调整堆
void heap_down(int dis,int v,int num){
while(num*2<heap_num){
int left=num*2;
int right=num*2+1;
if(dis>heap[left]||(right<heap_num&&dis>heap[right])){
int min=left;
if(right<heap_num&&heap[min]>heap[right]){
min=right;
}
int temp=heap[num];
heap[num]=heap[min];
heap[min]=temp;
dp[vdp[num]]=min;
dp[vdp[min]]=num;
vdp[num]=vdp[min];
vdp[min]=v;
num=min;
}
else break;
}
}
//自底向上调整堆
void heap_up(int dis,int v,int num){
while(num>1){
if(heap[num/2]>dis){
int temp=heap[num];
heap[num]=heap[num/2];
heap[num/2]=temp;
dp[v]=num/2;
dp[vdp[num/2]]=num;
vdp[num]=vdp[num/2];
vdp[num/2]=v;
num=num/2;
}
else break;
}
}
//堆的插入
void heap_insert(int dis,int v){
if(heap_num==1){
heap[1]=dis;
dp[v]=1;
vdp[1]=v;
heap_num++;
return;
}
heap[heap_num]=dis;
dp[v]=heap_num;
vdp[heap_num]=v;
heap_num++;
heap_up(dis,v,heap_num-1);
}
void heap_update(int dis,int v){
heap[dp[v]]=dis;
heap_up(dis,v,dp[v]);
}
//堆的删除
void heap_delete(){
if(heap_num==2){
dp[vdp[1]]=-1;
heap_num--;
return;
}
heap[1]=heap[heap_num-1];
dp[vdp[1]]=-1;
vdp[1]=vdp[heap_num-1];
dp[vdp[heap_num-1]]=1;
vdp[heap_num-1]=-1;
heap_num--;
heap_down(heap[1],vdp[1],1);
}
//堆优化的单源最短路算法
void dijkstra(){
int k,i,j,min;
dist[1]=0;
heap_insert(0,1);
for(i=1;i<=n;i++){
if(heap_num>1){
min=heap[1];
k=vdp[1];
heap_delete();
}
else break;
visit[k]=1;
for(j=0;j<edge[k].size();j++)
if(!visit[edge[k][j].v]&&dist[edge[k][j].v]>min+edge[k][j].dis){
dist[edge[k][j].v]=min+edge[k][j].dis;
if(dp[edge[k][j].v]!=-1)
heap_update(dist[edge[k][j].v],edge[k][j].v);
else heap_insert(dist[edge[k][j].v],edge[k][j].v);
}
}
}
int main(){
while(cin>>n>>m){
if(!n&&!m)
break;
for(int i=0;i<102;i++)
edge[i].clear();
for(i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
Edge e;
e.v=b;e.dis=c;
edge[a].push_back(e);
e.v=a;e.dis=c;
edge[b].push_back(e);
}
heap_num=1;
for(i=1;i<=n;i++){
dist[i]=INF;
visit[i]=0;
dp[i]=-1;
vdp[i]=-1;
heap[i]=-1;
}
dijkstra();
cout<<dist[n]<<endl;
}
}