标签:技术分享 fine vector gif heap eof record 队列 ems
其他链接
来自以上题解的图片来自常暗踏阴
使用前向星链表存图
直接用队列优化spfa
struct cmp { bool operator()(int a,int b) { return dist[a]>dist[b]; } }; priority_queue<int,vector<int>,cmp> q;void dijspfa() { q.push(s); memset(inq,0,sizeof(inq)); memset(dist,0x7f,sizeof(dist)); dist[s]=0; while(!q.empty()) { int u=q.top(); q.pop();inq[u]=0; for(int j=first[u];j>0;j=e[j].nxt) { if(e[j].len+dist[u]<dist[e[j].to]) { dist[e[j].to]=dist[u]+e[j].len; if(inq[e[j].to]==0) { q.push(e[j].to);inq[e[j].to]=1; } } } } }
dijspfa特性
1.判负环
spfa判负环主要用dfs,因为dfs判负环可以及时退出防止超时,
数据强化可以用bfs看下面
dijspfa判负环继承spfa的功能
但是可能过不了233
SPjkstra算法--就是本文的dijspfa
2.与dij,spfa比较
dij的思想是堆优化后从小到大松弛,每个点只入队一次
spfa的思想是不断修改子节点,使每个点重复入队更新,因此可以判负环
时间差异就在重复入队上
完整代码
1 #include<iostream> 2 #include<queue> 3 #include<cstdio> 4 #include<cstring> 5 #define Mx 200001 6 #define Nx 100001 7 using namespace std; 8 struct edge 9 { 10 int to,nxt,len; 11 }e[Mx]; 12 int first[Nx]; int n,m,s; 13 void addstar(int i,int u,int v,int w) 14 { 15 e[i].len=w; 16 e[i].nxt=first[u]; 17 e[i].to=v; 18 first[u]=i; 19 } 20 int inq[Nx]; 21 int dist[Nx]; 22 23 struct cmp 24 { 25 bool operator()(int a,int b) 26 { 27 return dist[a]>dist[b]; 28 } 29 }; 30 31 priority_queue<int,vector<int>,cmp> q; 32 void dijspfa() 33 { 34 q.push(s); 35 memset(inq,0,sizeof(inq)); 36 memset(dist,0x7f,sizeof(dist)); 37 dist[s]=0; 38 while(!q.empty()) 39 { 40 int u=q.top(); 41 q.pop();inq[u]=0; 42 for(int j=first[u];j>0;j=e[j].nxt) 43 { 44 if(e[j].len+dist[u]<dist[e[j].to]) 45 { 46 dist[e[j].to]=dist[u]+e[j].len; 47 if(inq[e[j].to]==0) 48 { 49 q.push(e[j].to);inq[e[j].to]=1; 50 } 51 } 52 } 53 } 54 } 55 int main() 56 { 57 memset(first,0,sizeof(first)); 58 cin>>n>>m>>s; 59 for(int i=1;i<=m;++i) 60 { 61 int a,b,c; 62 cin>>a>>b>>c; 63 addstar(i,a,b,c); 64 } 65 dijspfa(); 66 for(int i=1;i<=n;++i) 67 { 68 cout<<dist[i]<<" "; 69 } 70 return 0; 71 }
标签:技术分享 fine vector gif heap eof record 队列 ems
原文地址:https://www.cnblogs.com/dormin/p/9976089.html