a674498248 @ 2024-05-09 18:39:28
public class Main {
static int[] head = new int[(int)1e5 + 1];
static int cnt = 0;
static int n;
static int m;
static edge[] edges = new edge[2 * (int)1e5 + 1];
static boolean[] vis = new boolean[(int)1e5 + 1];
static int[] dist = new int[(int)1e5 + 1];
public static void main(String[] args) {//链表法
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
int s = sc.nextInt();
/*邻接表法
* int[][] graph = new int[n+1][n+1];
* */
//链表法(尾插)
/*
List<List<int[]>> list = new ArrayList<>();
for(int i = 1;i<=n;i++){
list.add(new ArrayList<>());
}
for(int i=0;i<m;i++){
int u = sc.nextInt();
int v = sc.nextInt();
int w = sc.nextInt();
List<int[]> list1 = list.get(u);
list1.add(new int[]{v, w});
list.set(u,list1);
}
//输出
for(List<int[]> l : list){
for(int[] i : l){
System.out.print(Arrays.toString(i) + " ");
}
System.out.println("\n" + "-----------");
}
*/
//链式前向星又称为链表法(头插)
init();
for(int i = 0; i < m;i++){//m条边
int u = sc.nextInt();
int v = sc.nextInt();
int w = sc.nextInt();
add_edge(u,v,w);
}
/* 输出
for(int i = 1; i <= n;i++){
//遍历i个节点
System.out.println(i);
for(int j = head[i];j!=-1;j = edges[j].next){
//遍历i的所有临接边
System.out.print("["+i + "," + edges[j].to + "," + edges[j].weight+"]" + " ");
}
System.out.print("\n");
System.out.println("-------------------");
}
*/
Dijkstra(s);
for(int i = 1; i <= n;i++){
System.out.print(dist[i] + " ");
}
}
public static void init(){
for(int i = 0;i<=n;i++){
head[i] = -1;
}
cnt = 0;
}
public static void add_edge(int u, int v, int weight){
edges[cnt] = new edge();//新建边
edges[cnt].to = v;
edges[cnt].weight = weight;
edges[cnt].next = head[u];
head[u] = cnt++;//先赋值完再加加
}
static class edge{
public int to;//终止节点
public int weight;//权值
public int next;//下一个节点
}
static void Dijkstra(int s){//堆优化版本
Arrays.fill(dist,Integer.MAX_VALUE);
dist[s] = 0;
//压入格式为{v,w}
PriorityQueue<int[]> que = new PriorityQueue<>((a,b) -> b[1] - a[1]);//从小到大
que.offer(new int[]{s,0});
while(!que.isEmpty()){
int[] now_point = que.poll();
int u = now_point[0];
int w = now_point[1];
if(vis[u]) continue;//将该点置为已访问
vis[u] = true;
//遍历该点的所有邻接点
for(int i = head[u]; i != -1; i = edges[i].next){;
int v = edges[i].to;//到达点
//如果dist[到达点] > 当前点的最短距离+到达下一个点的距离 置换
if(dist[v] > w + edges[i].weight){
dist[v] = w + edges[i].weight;
if(!vis[v]){
que.offer(new int[]{v,dist[v]});
}
}
}
}
}
}