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)