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 }
View Code

 

先上题目链接

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 }
View Code

 

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 };
View Code

 

posted @ 2020-11-03 13:50  剩下的交给时间就好  阅读(68)  评论(0编辑  收藏  举报