//https://paste.ubuntu.com/p/R2dkdC5RDh/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
const int MAX = 10005 ;
const int inf =0x3f3f3f3f ;
using namespace std ;
//Dijkstra 队列优化
struct qnode{
int v ; // 节点编号
int c ; // 到起点的距离
qnode(int _v =0 ,int _c =0 ):v(_v),c(_c){
} ;
bool operator <(const qnode &r)const {
return c>r.c ;
}
};
struct Edge{
int v;// 边的终点和权值
int w ;
Edge(int _v=0 ,int _w =0):v(_v),w(_w){
//初始化
}
};
vector <Edge> e[MAX] ;
bool vis[MAX] ;
int dis[MAX] ;
int n ,m ;
void Dijkstra(int cur)
{
memset(vis,false ,sizeof(vis)) ;
for(int i = 1 ;i<=n ;i++)
{
dis[i] = inf ;
}
priority_queue<qnode> que ;
// 按照节点到起点的距离大小作为出队列的依据
// 距离最近的先出
// while(!que.empty())
// {
// // 初始化队列
// que.pop();
// }
dis[cur] = 0 ;
que.push(qnode(cur,0)); // 将源点放入,距离为0
qnode tmp ;
while(!que.empty()) // 广搜找通路
{
tmp = que.top();
que.pop() ;
int u = tmp.v ; // 找距离最近的编号
if(vis[u])
continue ;
vis[u] = true ;// 标记访问过了
// 下面是松弛操作 ;
for(int i = 0 ;i<e[u].size();i++)
{
int v = e[u][i].v ;
int w = e[u][i].w ;
if(!vis[v] && dis[v] > dis[u]+w)
{
dis[v] = dis[u]+w ;
que.push(qnode(v,dis[v]));
}
}
}
}
void addedge(int u ,int v ,int w)
{
e[u].push_back(Edge(v,w)) ;
e[v].push_back(Edge(u,w)) ;
return ;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0 && m==0)
{
break ;
}
while(m--)
{
int u ,v ,w ;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
Dijkstra(1);
printf("%d\n",dis[n]);
for(int i = 1 ;i<=n ;i++)
{
e[i].clear();
}
}
return 0 ;
}
链式前向星存边+队列优化
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std ;
const int MAX = 200005 ;
const int inf = 0x3f3f3f3f ;
struct Edge{
int to ;
int next ;
int w ;
};
struct node{
int u ;
int d ;
bool operator < (const node &x)const
{
return d > x.d ;
}
};
Edge edge[MAX] ;
int n , m , s ;
int head[MAX] ;
int cnt ;
int dis[MAX] ;
bool vis[MAX] ;
inline int read()
{
int x=0,k=1; char c=getchar();
while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*k;
}//快读
void Add(int u , int v ,int w )
{
cnt++ ;
edge[cnt].next = head[u] ;
edge[cnt].to = v ;
edge[cnt].w = w ;
head[u] = cnt ;
}
inline void Dijkstra(int s)
{
priority_queue<node> q ;
for(int i = 1 ; i<=n ;i++)
{
dis[i] = inf ;
vis[i] = false ;
}
dis[s] = 0 ;
q.push({s,0});
while(!q.empty())
{
node tmp = q.top() ;
q.pop();
int u = tmp.u ;
if(vis[u])
continue ;
vis[u] = true ;
for(int i = head[u] ; i ; i = edge[i].next)
{
int v = edge[i].to ;
int d = edge[i].w ;
if(dis[v] > dis[u] +d)
{
dis[v] = dis[u]+d ;
if(!vis[v])
{
q.push({v,dis[v]});
}
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
cnt = 0 ;
if(n==0 && m==0)
break ;
for(int i = 0 ; i<= n ;i++)
head[i] = 0 ;
memset(edge,0,sizeof(edge));
for(int i = 1 ; i<=m ;i++)
{
int u , v ,w ;
u = read() ;
v = read() ;
w = read() ;
Add(u,v,w) ;
Add(v,u,w) ;
}
Dijkstra(1);
printf("%d\n",dis[n]);
}
return 0 ;
}