P1339 [USACO09OCT] Heat Wave G

题解

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

 

posted @ 2024-03-27 22:48  黑屿白  阅读(30)  评论(0)    收藏  举报