Cod sursa(job #1844734)

Utilizator GoogalAbabei Daniel Googal Data 10 ianuarie 2017 13:20:07
Problema Algoritmul lui Dijkstra Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.24 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define nmax 36001
#define INF 1<<30

using namespace std;

ifstream fin("catun.in");
ofstream fout("catun.out");

int k,n,m,x;
long long heap[nmax],poz[nmax];

pair < long long , int > cost[nmax];

vector < pair < int, int > > leg[nmax];

inline int father(int k)
{
    return k/2;
}

inline int leftson(int k)
{
    return k*2;
}

inline int rightson(int k)
{
    return k*2+1;
}

void sift(int n, int k)
{
    int son;
    do
    {
        son=0;
        if(leftson(k)<=n)
        {
            son=leftson(k);
            if(rightson(k)<=n && cost[heap[leftson(k)]].first>cost[heap[rightson(k)]].first)
                son=rightson(k);
            if(cost[heap[son]].first>=cost[heap[k]].first)
                son=0;
        }

        if(son)
        {
            swap(heap[k], heap[son]);
            swap(poz[heap[k]],poz[heap[son]]);
            k=son;
        }
    }
    while(son);
}

void percolate(int n, int k)
{
    int key=heap[k];
    while(k>1 && cost[key].first<cost[heap[father(k)]].first)
    {
        heap[k]=heap[father(k)];
        poz[heap[k]]=k;
        k=father(k);
    }

    heap[k]=key;
    poz[heap[k]]=k;
}

void delete_elem(int &n, int k)
{
    heap[k]=heap[n];
    poz[heap[k]]=k;
    n--;
    if(k>1 && cost[heap[k]].first<cost[heap[father(k)]].first)
        percolate(n,k);
    else
        sift(n,k);
}

inline void solve()
{
    int node,a,b,i;
    while(k)
    {
        node=heap[1];
        delete_elem(k,1);
        for(i=0; i<leg[node].size(); i++)
        {
            a=leg[node][i].first;
            b=leg[node][i].second;
            if(cost[a].first>cost[node].first+b)
            {
                cost[a].first=cost[node].first+b;
                cost[a].second=cost[node].second;
            }
            else if(cost[a].second!=a && cost[a].first==cost[node].first+b && cost[a].second>cost[node].second)
                cost[a].second=cost[node].second;
            if(poz[a]>1 && cost[a].first<cost[heap[father(poz[a])]].first)
                percolate(k, poz[a]);
            else
                sift(k, poz[a]);
        }
    }
}

inline void read()
{
    int i,a,b,c;
    fin>>n>>m>>k;
    for(i=1; i<=k; i++)
    {
        fin>>x;
        heap[i]=x;
        cost[x].second=x;
    }

    sort(heap+1,heap+k+1);

    for(i=1;i<=k;i++)
        poz[heap[i]]=i;

    for(i=2; i<=k; i++)
    {
        leg[heap[i]].push_back(make_pair(heap[1],0));
        leg[heap[1]].push_back(make_pair(heap[i],0));
    }

    i=1;
    for(int j=1; j<=n; j++)
    {
        if(heap[i]!=j)
        {
            heap[++k]=j;
            cost[j].first=INF;
            poz[j]=k;
        }
        else
            i++;
    }
    for(i=1; i<=m; i++)
    {
        fin>>a>>b>>c;
        leg[a].push_back(make_pair(b,c));
        leg[b].push_back(make_pair(a,c));
    }
    fin.close();
}

inline void write()
{
    for(int i=1; i<=n; i++)
    {
        if(cost[i].first==INF || cost[i].second==i)
            fout<<"0 ";
        else
            fout<<cost[i].second<<' ';
    }
}

int main()
{
    read();
    solve();
    write();
    return 0;
}