Cod sursa(job #2283846)

Utilizator danielsociuSociu Daniel danielsociu Data 15 noiembrie 2018 22:27:30
Problema Algoritmul lui Dijkstra Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <fstream>
#include <vector>
#include <cstring>
std::ifstream cin("dijkstra.in");
std::ofstream cout("dijkstra.out");
#define maxn 50050
#define it std::vector<std::pair<int,int>>::iterator
inline void swap(int &a,int &b){int aux;aux=a;a=b;b=aux;}
const int INF = 1<<30;
std::vector<std::pair<int,int>> g[maxn];
int n,m,k;
int h[maxn],poz[maxn],d[maxn];

void dijkstra_wHeap();
void downheap(int);
void upheap(int);

int main()
{
    int x,y,z;
    cin>>n>>m;
    for(;--m;){
        cin>>x>>y>>z;
        g[x].push_back(std::make_pair(y,z));
    }
    dijkstra_wHeap();
    for(int i=2;i<=n;i++){
        x=((d[i]==INF)?0:d[i]);
        cout<<x<<' ';
    }
    cout<<'\n';
    return 0;
}

void dijkstra_wHeap(){
    for(int i=2;i<=n;i++)
        d[i]=INF, poz[i]=-1;
    h[++k]=1;
    poz[1]=1;
    while(k){
        int mini=h[1];
        swap(h[k],h[1]);
        poz[h[1]]=1;
        --k;
        downheap(1);

        for(it xd=g[mini].begin();xd!=g[mini].end();xd++){
            if(d[xd->first]>d[mini]+xd->second){ //xd pointer ->
                d[xd->first]=d[mini]+xd->second; //nu se foloseste .
                if(poz[xd->first]!=-1)
                    upheap(poz[xd->first]);
                else{
                    h[++k]=xd->first;
                    poz[h[k]]=k;
                    upheap(k);
                }
            }
        }
    }
}

void upheap(int x){
    int tata=x;
    while(x>1){
        tata=x>>1;
        if(d[h[tata]]>d[h[x]]){
            poz[h[tata]]=x;
            poz[h[x]]=tata;
            swap(h[x],h[tata]);
            x=tata;
        }else
            x=1;
    }
}

void downheap(int x){
    int f;
    while(x<=k){
        f=x;
        if((x<<1)<=k){
            f=x<<1;
            if(f+1<=k)
                if(d[h[f]]>d[h[f+1]])
                    f++;
        }
        else
            return;
        if(d[h[f]]<d[h[x]]){
            poz[h[f]]=x;
            poz[h[x]]=f;
            swap(h[f],h[x]);
            x=f;
        }
        else
            return;
    }
}