spfa slf優化
阿新 • • 發佈:2018-11-08
/*SPFA演算法有兩個優化演算法 SLF 和 LLL: SLF:Small Label First 策略,設要加入的節點是j,隊首元素為i,若dist(j) < dist(i),則將j插入隊首,否則插入隊尾。 LLL:Large Label Last 策略,設隊首元素為i,每次彈出時進行判斷,佇列中所有dist值的平均值為x,若dist(i)>x則將i插入到隊尾,查詢下一元素,直到找到某一i使得dist(i)<=x,則將i出對進行鬆弛操作。 */ //小的dis在前 #include<bits/stdc++.h> using namespace std;int n,m,s;//起點終點開頭 int u[200005],v[200005],w[200005]; int first[200005],nextt[200005]; int dis[200005]; int k2=0; void make_edge(int a,int b,int c) { k2++; u[k2]=a; v[k2]=b; w[k2]=c; nextt[k2]=first[a]; first[a]=k2; } void clean() { int flag=max(n,m); for(int i=1;i<=flag;i++) { first[i]=-1; nextt[i]=-1; } for(int i=1;i<=n;i++) { if(i==s) dis[i]=0; else dis[i]=1e9; } } deque<int> q; int book[200005]; int main() { cin>>n>>m>>s; clean(); for(int i=1;i<=m;i++) { int a,b,c; cin>>a>>b>>c; make_edge(a,b,c); } q.push_back(s); book[s]=1; while(!q.empty()) { int now_node=q.front(); q.pop_front(); book[now_node]=0; int k=first[now_node]; while(k!=-1) { if(dis[v[k]]>dis[u[k]]+w[k]) { dis[v[k]]=dis[u[k]]+w[k]; if(book[v[k]]==0) { book[v[k]]=1; if(dis[v[k]]<dis[now_node]&&!q.empty()/*記得判空*/) { q.push_front(v[k]); } else q.push_back(v[k]); } } k=nextt[k]; } } for(int i=1;i<=n;i++) { if(i==1) cout<<dis[i]; else cout<<" "<<dis[i]; } cout<<endl; return 0; }