【luogu4779】【模板】单源最短路经 [Dijkstra]
记录的一些杂七杂八的模板 中间嵌杂一些记不到的小语法 多打几遍
1 /* 2 id:gww 3 language:C-- 4 Dijksra+堆优化 5 */ 6 #include<bits/stdc++.h> 7 using namespace std; 8 const int N=100000+5,M=200000+5,inf=2147483647; 9 int n,m,S; 10 inline int rd() 11 { 12 int x=0,w=0;char ch=0; 13 while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} 14 while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); 15 return w?-x:x; 16 } 17 18 int head[N],tot=0; 19 struct edge 20 { 21 int v,nxt,w; 22 }e[M]; 23 void add(int u,int v,int w) 24 { 25 e[++tot].v=v; 26 e[tot].w=w; 27 e[tot].nxt=head[u]; 28 head[u]=tot; 29 } 30 31 struct node 32 { 33 int dis,pos; 34 node():dis(0),pos(0){}//无参数初始化 35 node(int a,int b):dis(a),pos(b){}//带参初始化 36 bool operator <(const node &x)const 37 {return x.dis<dis;}//从小到大 38 }; 39 int dis[N];bool vis[N]; 40 priority_queue<node> q; 41 void dijkstra(int s) 42 { 43 // memset(dis,inf,sizeof(dis)); 44 // memset(vis,inf,sizeof(vis)); 45 for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=0; 46 dis[s]=0; 47 q.push(node(0,s)); 48 while(q.size()) 49 { 50 int u=q.top().pos;q.pop(); 51 if(vis[u]) continue; 52 vis[u]=1; 53 for(int i=head[u];i;i=e[i].nxt) 54 { 55 int v=e[i].v,w=e[i].w; 56 if(dis[v]>dis[u]+w) 57 { 58 dis[v]=dis[u]+w; 59 q.push(node(dis[v],v)); 60 } 61 } 62 } 63 } 64 65 int main() 66 { 67 n=rd(),m=rd(),S=rd(); 68 for(int i=1;i<=m;i++) 69 { 70 int u=rd(),v=rd(),w=rd(); 71 add(u,v,w); 72 } 73 dijkstra(S); 74 for(int i=1;i<=n;i++) printf("%d ",dis[i]); 75 return 0; 76 }
弱化版spfa做法 可以拿来对比着区分一下两种算法的写法 spfa拿来处理环那些比较适合用
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=10010; 4 const int maxm=500010; 5 int n,m,s,cnt=0; 6 int head[maxn],dis[maxn],vis[maxn]; 7 8 struct edge 9 { 10 int u,w,v,next; 11 }e[maxm]; 12 13 void add(int u,int v,int w) 14 { 15 cnt++; 16 e[cnt].u=u; 17 e[cnt].v=v; 18 e[cnt].w=w; 19 e[cnt].next=head[u]; 20 head[u]=cnt; 21 } 22 queue<int> q; 23 void spfa() 24 { 25 q.push(s); 26 dis[s]=0;vis[s]=1; 27 while(!q.empty()) 28 { 29 int u=q.front(); 30 q.pop();vis[u]=0; 31 for(int i=head[u];i!=-1;i=e[i].next) 32 { 33 int v=e[i].v,w=e[i].w; 34 if(dis[v]>dis[u]+w) 35 { 36 dis[v]=dis[u]+w; 37 if(vis[v]==0) 38 { 39 q.push(v); 40 vis[v]=1; 41 } 42 } 43 } 44 } 45 } 46 47 int main() 48 { 49 scanf("%d%d%d",&n,&m,&s); 50 memset(head,-1,sizeof(head)); 51 memset(vis,-0,sizeof(vis)); 52 for(int i=0;i<=n;i++) 53 { 54 dis[i]=2147483647; 55 } 56 for(int i=1;i<=m;i++) 57 { 58 int u,w,v; 59 scanf("%d%d%d",&u,&v,&w); 60 add(u,v,w); 61 } 62 spfa(); 63 for(int i=1;i<=n;i++) 64 { 65 if(s==i) printf("0 "); 66 else printf("%d ",dis[i]); 67 } 68 return 0; 69 }
优先队列语法参考:
struct node{ int dis,pos; node():dis(0),pos(0){}//无参初始化 node(int a,int b):dis(a),pos(b){}//带参初始化 bool operator <(node x)const //重载小于运算,用于把priority_queue变成小根堆 { return dis>x.dis; } }; 然后在主模块中这样操作: priority_queue<node> q; q.push(node(x,0)); node cur=q.top(); q.pop(); q.push(cur);