题解
Dijkstra算法的应用,我这里采用了 堆结构优化+反向索引堆优化 最大化的优化了时间复杂度。题解区的复杂度是O(mlogm)而我优化后达到了O((n+m)logn)即复杂度和点的个数相关,而非边的条数。
code
#include<bits/stdc++.h> using namespace std; const int N=6200*2+5; int n,m,s,t,cnt2=1; int head[2505],Next[N],to[N],w[N],vis[2505],cnt[2505]; struct Node{ int way,value; }; Node heap[2505]; int len=0; void initial(){ for (int i=1;i<=n;i++){ vis[i]=-1; cnt[i]=1e9; } } void heapinsert(int id,int weight){ Node x; x.way=id; x.value=weight; if (vis[id]==-1) { vis[id]=len; cnt[id]=weight; heap[len++]=x; } int i=vis[id]; while (i>0){ int l=(i-1)/2; if (heap[l].value<=heap[i].value) break; else { vis[heap[l].way]=i; vis[id]=l; swap(heap[l],heap[i]); i=l; } } } void heapfy(int i){ int l=i*2+1; while (l<len){ int best=l+1<len && heap[l+1].value<heap[l].value ? l+1 : l; best=heap[best].value>=heap[i].value ? i : best; if (best==i) break; vis[heap[best].way]=i; vis[heap[i].way]=best; swap(heap[i],heap[best]); i=best; l=i*2+1; } } void build(){ int from,To,value; cin>>from>>To>>value; Next[cnt2]=head[from]; to[cnt2]=To; w[cnt2]=value; head[from]=cnt2; cnt2++; Next[cnt2]=head[To]; to[cnt2]=from; w[cnt2]=value; head[To]=cnt2; cnt2++; } int main(){ cin>>n>>m>>s>>t; initial(); for (int i=1;i<=m;i++) build(); heapinsert(s,0); cnt[s]=0; while (true){ Node x=heap[0]; vis[x.way]=-2; heap[0]=heap[--len]; heapfy(0); // cout<<x.way<<" "<<x.value<<endl<<endl; // for (int j=0;j<len;j++) cout<<heap[j].way<<" "<<heap[j].value<<endl; // cout<<endl; if (x.way==t){ cout<<x.value<<endl; break; } else { for (int i=head[x.way];i>0;i=Next[i]){ // cout<<to[i]<<" "<<w[i]<<" "<<vis[to[i]]<<endl; if (vis[to[i]]==-1) heapinsert(to[i],x.value+w[i]); if (vis[to[i]]==-2) continue; else { if (x.value+w[i]<cnt[to[i]]){ cnt[to[i]]=x.value+w[i]; heap[vis[to[i]]].value=cnt[to[i]]; heapinsert(to[i],cnt[to[i]]); } } // for (int j=0;j<len;j++) cout<<heap[j].way<<" "<<heap[j].value<<endl; // cout<<endl; } } } return 0; }
标签:value,head,int,USACO09OCT,Heat,P1339,heap,best,cnt2 From: https://www.cnblogs.com/purple123/p/18100505