P3371 【模板】单源最短路径(弱化版)

题目链接 https://www.luogu.com.cn/problem/P3371


 

Dijkstra+链式前向星

(因为数据范围太大,用邻接矩阵会炸)

放AC代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,s;
 4 int a,b,c;
 5 int cnt;
 6 int head[20010];
 7 bool vis[20010];
 8 long long dis[20010];
 9 
10 struct edge
11 {
12     int v;
13     int w;
14     int next;
15 }edge[1000010];
16 
17 void add(int a,int b,int c)
18 {
19     edge[++cnt].v=b;
20     edge[cnt].w=c;
21     edge[cnt].next=head[a];
22     head[a]=cnt;
23 }
24 
25 int main()
26 {
27     cin>>n>>m>>s;
28     
29     for(int v=1;v<=n;v++)
30         dis[v]=INT_MAX;
31         
32     for(int e=0;e<m;e++)
33     {
34         cin>>a>>b>>c;
35         add(a,b,c);
36     }
37     
38     int cur=s;
39     dis[s]=0;
40     long long minn;
41     
42     while(!vis[cur])//已搜完整张图
43     {
44         vis[cur]=true;//标记,已收录到最优路径集合中
45         
46         for(int i=head[cur];i!=0;i=edge[i].next)
47         {//链式前向星搜边(更新未求集合中的每一个距离)
48             if(!vis[edge[i].v]&&dis[edge[i].v]>dis[cur]+edge[i].w)
49             //A点能够到达的点B未收录到最优路径集合中
50             //且(节点A的距离+节点A到节点B的边长)<节点B的距离
51                 dis[edge[i].v]=dis[cur]+edge[i].w;
52         }
53         
54         minn=INT_MAX;
55         for(int i=1;i<=n;i++)
56         {//打擂台,求未来集合中的最短距离
57             if(!vis[i]&&dis[i]<minn)
58             {
59                 minn=dis[i];
60                 cur=i;//cur为此时所有未录入集合中到起点的边最短的点
61             }
62         }
63     }
64     
65     for(int i=1;i<=n;i++)
66         cout<<dis[i]<<" ";
67     return 0;
68 }

 

—————————————————————更(4.29)——————————————————————

 

Dijktra堆优化版

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
 4 int n,m,s;
 5 int cnt;
 6 int head[20010];
 7 bool vis[20010];
 8 long long dis[20010];
 9 
10 struct Edge
11 {
12     int v;
13     int w;
14     int next;
15 } edge[1000010];
16 
17 void add(int u,int v,int w)
18 {
19     edge[++cnt].v=v;
20     edge[cnt].w=w;
21     edge[cnt].next=head[u];
22     head[u]=cnt;
23 }
24 
25 int main()
26 {
27     cin>>n>>m>>s;
28     for(int i=1; i<=m; i++)
29     {
30         int u,v,w;
31         cin>>u>>v>>w;
32         add(u,v,w);
33     }
34     for(int i=1; i<=n; i++)
35     {
36         dis[i]=INT_MAX;
37     }
38     dis[s]=0;
39     q.push(make_pair(0,s));
40     while(!q.empty())
41     {
42         int point=q.top().second;
43         q.pop();
44         if(vis[point])
45             continue;
46         vis[point]=1;
47         for(int i=head[point]; i!=0; i=edge[i].next)
48         {
49             if(dis[edge[i].v]>dis[point]+edge[i].w)
50             {
51                 dis[edge[i].v]=dis[point]+edge[i].w;
52                 q.push(make_pair(dis[edge[i].v],edge[i].v));
53             }
54         }
55     }
56     for(int i=1; i<=n; i++)
57         cout<<dis[i]<<" ";
58     return 0;
59 }

 

————————————————————学完SPFA再来更—————————————————————

um....忘记了,懒得更了(5.8)

 

posted @ 2022-04-25 21:29  爱吃虾滑  阅读(57)  评论(0编辑  收藏  举报