#include<queue>
#include<map>
#include<string>
#include<iostream>
#define INF 0x3f3f3f3f
#define maxn 1010
using namespace std;
//堆優化+vector<Edge>
//類
struct qnode{//堆結點
int v;//頂點編號
int dis;//頂點到起點的距離
qnode(int v,int d):v(v),dis(d){
} ;
qnode(){
};
friend bool operator < (qnode a,qnode b){//默認<,最大堆
return a.dis>b.dis;//最小堆
}
};
struct Edge{
//從某個頂點出發到達點v花費c
int v;
int c;
Edge(int v,int c):v(v),c(c){
};
};
class Graph{
vector<Edge> E[maxn];//圖,鄰接表
bool vis[maxn];
int dis[maxn];
int path[maxn];
int n;
int sc,di;
public:
void addEdge(int u,int v,int w){
E[u].push_back(Edge(v,w));
}
void init(){
int m;
cin>>n>>m;
int u,v,w;
for(int i=0;i<m;i++){
cin>>u>>v>>w;
addEdge(u,v,w);
//雙向 addEdge(v,u,w);
}
}
void init2(int start,int end){
sc=start;
di=end;
}
void dijkstra(){
//init
for(int i=1;i<=n;i++){
dis[i]=INF;
vis[i]=0;
path[i]=-1;
}
dis[sc]=0;
//
priority_queue<qnode> Q;
Q.push(qnode(sc,0));
//
qnode tmp;
while(!Q.empty()){
//findmin
tmp=Q.top();Q.pop();
int u=tmp.v;
if(vis[u])continue;
vis[u]=true;
//鬆弛
for(int i=0;i<E[u].size();i++){//點u所有的出邊
int v=E[u][i].v;
int cost=E[u][i].c;
if(!vis[v]&&dis[v]>dis[u]+cost){
dis[v]=dis[u]+cost;
path[v]=u;
//將被鬆弛過的點加入隊列
Q.push(qnode(v,dis[v]));
}
}
}
}
void put(){
for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
}
};
int main(){
Graph G;
G.init();
G.init2(1,5);
G.dijkstra();
G.put();
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<string>
#include<iostream>
#define INF 0x3f3f3f3f
#define maxn 1010
using namespace std;
//堆優化+vector<Edge>
struct qnode{//堆結點
int v;//頂點編號
int dis;//頂點到起點的距離
qnode(int v,int d):v(v),dis(d){
} ;
qnode(){
};
friend bool operator < (qnode a,qnode b){//默認<,最大堆
return a.dis>b.dis;//最小堆
}
};
struct Edge{
//從某個頂點出發到達點v花費c
int v;
int c;
Edge(int v,int c):v(v),c(c){
};
};
vector<Edge> E[maxn];//圖,鄰接表
void addEdge(int u,int v,int w){
E[u].push_back(Edge(v,w));
}
bool vis[maxn];
int dis[maxn];
int path[maxn];
int n;
int sc,di;
void dijkstra(int sc){
//init
for(int i=1;i<=n;i++){
dis[i]=INF;
path[i]=-1;
}
dis[sc]=0;
//
priority_queue<qnode> Q;
Q.push(qnode(sc,0));
//
qnode tmp;
while(!Q.empty()){
//findmin
tmp=Q.top();Q.pop();
int u=tmp.v;
if(vis[u])continue;
vis[u]=true;
//鬆弛
for(int i=0;i<E[u].size();i++){//點u所有的出邊
int v=E[u][i].v;
int cost=E[u][i].c;
if(!vis[v]&&dis[v]>dis[u]+cost){
dis[v]=dis[u]+cost;
path[v]=u;
//將被鬆弛過的點加入隊列
Q.push(qnode(v,dis[v]));
}
}
}
}
int main(){
int m;
cin>>n>>m;
int u,v,w;
for(int i=0;i<m;i++){
cin>>u>>v>>w;
addEdge(u,v,w);
//雙向 addEdge(v,u,w);
}
sc=1;//從1開始
dijkstra(sc);
for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
return 0;
}
/*//最簡單的鄰接矩陣實現
bool vis[maxn];
int path[maxn];
int g[maxn][maxn];
int dis[maxn];
int n,m;
int sc,di;//起點與終點;
void dijkstra(int sc){
//初始化dis[],vis[],path[]
for(int i=0;i<n;i++){
dis[i]=INF;
vis[i]=0;
path[i]=-1;
}
dis[sc]=0;
// findmin
while(1){
int mindis=INF,minv=-1;
for(int j=0;j<n;j++){
if(!vis[j]&&dis[j]<mindis){
mindis=dis[j];
minv=j;
}
}
//找不到未在集合中的點則退出(所有點都包含進集合)
if(minv==-1) break;
vis[minv]=1;
cout<<"minv= "<<minv<<endl;
//鬆弛操作 (對不在集合中的點)
for(int i=0;i<n;i++){
if(!vis[i]&&dis[i]>dis[minv]+g[minv][i]){
cout<<"A";
dis[i]=dis[minv]+g[minv][i];
path[i]=minv;
}
}
}
}
int main(){
cin>>n>>m;
//定義頂點編號從0--n-1
int u,v,w;
//初始化圖g
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
i==j?g[i][j]=0:g[i][j]=INF;
}
}
for(int i=0;i<m;i++){
cin>>u>>v>>w;
//有向圖
g[u-1][v-1]=w;
}
sc=0;
dijkstra(sc);
for(int i=0;i<n;i++){
cout<<dis[i]<<" ";
}
return 0;
}
*/