spfa与dij。前向星建图和vector建图
P4779 【模板】单源最短路径(标准版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
dij
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int macn=1e5+50; 4 const int macm=2e5+50; 5 int head[macn],vis[macn],dis[macn]; 6 int num,n,m,s,i,j; 7 struct edge{ 8 int v,w,next; 9 }a[macm]; 10 struct node{ 11 int index,distance; 12 bool operator <(node n)const{ 13 return distance>n.distance ; 14 } 15 }; 16 void inline add(int u,int v,int w){ 17 a[++num].v =v; 18 a[num].w =w; 19 a[num].next =head[u]; 20 head[u]=num; 21 } 22 void dij(){ 23 for(i=1;i<=n;i++){ 24 dis[i]=1e9; 25 //printf("%d ",dis[i]); 26 } 27 priority_queue<node>q; 28 dis[s]=0;//勿漏 29 q.push({s,0}); 30 while(!q.empty()){ 31 node t=q.top(); 32 q.pop(); 33 int x=t.index; 34 if(vis[x]) 35 continue; 36 vis[x]=1; 37 //printf("%d被访问,head[x]=%d\n",x,head[x]); 38 for(j=head[x];j!=0;j=a[j].next){ 39 int v=a[j].v ; 40 // printf("v=%d,dis[v]=%d,dis[x]=%d,a[j].w=%d\n",v,dis[v],dis[x],a[j].w); 41 if(dis[v]>dis[x]+a[j].w ){ 42 dis[v]=dis[x]+a[j].w; 43 // printf("%d结点被更新,dis=%d\n",v,dis[v]); 44 if(!vis[v]) 45 q.push((node){v,dis[v]}); 46 } 47 } 48 } 49 } 50 int main(){ 51 num=0; 52 int x,y,z; 53 cin>>n>>m>>s; 54 for(i=1;i<=m;i++){ 55 cin>>x>>y>>z; 56 add(x,y,z); 57 } 58 dij(); 59 for(i=1;i<=n;i++){ 60 cout<<dis[i]<<" "; 61 } 62 }
spfa
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int mac=4e5+50; 4 int head[mac],vis[mac],dis[mac]; 5 int n,m,num,i,j,t; 6 struct edge{ 7 int v,w,next; 8 }a[mac]; 9 void sc(){ 10 int x,y,z; 11 scanf("%d %d",&n,&m); 12 for(i=1;i<=m;i++){ 13 scanf("%d %d %d",&x,&y,&z); 14 a[++num]=(edge){y,z,head[x]}; 15 head[x]=num; 16 a[++num]=(edge){x,z,head[y]};//无向图 双向边,然后数组两倍边数 17 head[y]=num; 18 } 19 } 20 void spfa(){ 21 memset(dis,0x3f, sizeof(dis)); 22 deque<int>q; 23 q.push_back(1); 24 vis[1]=1; 25 dis[1]=0; 26 while(!q.empty()){ 27 t=q.front(); 28 q.pop_front(); 29 vis[t]=0; 30 for(j=head[t];j!=0;j=a[j].next){ 31 int v=a[j].v; 32 if(dis[v]>dis[t]+a[j].w){ 33 dis[v]=dis[t]+a[j].w; 34 if(!vis[v]) 35 { 36 vis[v]=1; 37 if(dis[v]<=dis[q.front()]) 38 q.push_front(v); 39 else 40 q.push_back(v); 41 } 42 } 43 } 44 } 45 if(dis[n]!=0x3f3f3f3f) 46 printf("%d\n",dis[n]); 47 else 48 cout<<"qwb baka"<<endl;//1和n不连通 49 } 50 int main(){ 51 sc(); 52 spfa(); 53 }
vector建图
2290. 到达角落需要移除障碍物的最小数目 - 力扣(LeetCode)
1 class Solution { 2 public: 3 int n,m; 4 vector<pair<int,int>>mp[100005]; 5 int dis[100005],vis[100005]; 6 int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; 7 int getid(int x,int y){ 8 return x*m+y;//一行有m个 9 } 10 void dij(vector<vector<int>>& grid){ 11 memset(dis,0x3f,sizeof(dis));dis[0] = 0;//用INT_MAX有加法会炸int 12 priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>que; 13 que.push({0,0}); 14 while(que.size()){ 15 auto u = que.top();que.pop();//u.first是排序依据,是0,0的id到u.first这个id的距离 16 if(vis[u.second])continue; 17 vis[u.second] = 1; 18 for(auto v : mp[u.second]){ 19 if(dis[v.second]>dis[u.second]+v.first){ 20 dis[v.second] = dis[u.second]+v.first; 21 que.push({dis[v.second],v.second}); 22 } 23 } 24 } 25 } 26 int minimumObstacles(vector<vector<int>>& grid) { 27 n = grid.size(); m = grid[0].size(); 28 for(int i=0;i<n;i++){ 29 for(int j=0;j<m;j++){ 30 for(auto [dx,dy] : dirs){ 31 if(i+dx<0||i+dx>=n||j+dy<0||j+dy>=m)continue; 32 mp[getid(i,j)].push_back({grid[i][j],getid(i+dx,j+dy)}); 33 } 34 } 35 } 36 dij(grid); 37 return dis[getid(n-1,m-1)]; 38 } 39 };