Cod sursa(job #2138439)

Utilizator inquisitorAnders inquisitor Data 21 februarie 2018 17:28:08
Problema Algoritmul lui Dijkstra Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.94 kb
#include <bits/stdc++.h>

__attribute__((always_inline)) void read(int &num)
{
    static char inBuffer[0x30D40];

    static unsigned int p = 0x30D3F; num = 0x0;

    while(inBuffer[p] < 0x30 | inBuffer[p] > 0x39)
    {
        ++p != 0x30D40 || (fread(inBuffer, 0x1, 0x30D40, stdin), p = 0x0);
    }

    while(inBuffer[p] > 0x2F & inBuffer[p] < 0x3A)
    {
        num = num * 0xA + inBuffer[p] - 0x30;

        ++p != 0x30D40 || (fread(inBuffer, 0x1, 0x30D40, stdin), p = 0x0);
    }
}

char outBuffer[0x61A80]; unsigned int p;

__attribute__((always_inline)) void write(unsigned int x)
{
    unsigned int digits = x > 0x3B9AC9FF ? 0xA :
                 x > 0x5F5E0FF  ? 0x9 :
                 x > 0x98967F   ? 0x8 :
                 x > 0xF423F    ? 0x7 :
                 x > 0x1869F    ? 0x6 :
                 x > 0x270F     ? 0x5 :
                 x > 0x3E7      ? 0x4 :
                 x > 0x63       ? 0x3 :
                 x > 0x9        ? 0x2 : 0x1;

    for(unsigned int i = ~-digits; ~i; --i)
    {
        outBuffer[p + i] = x % 0xA + 0x30;

        x = x / 0xA;
    }

    p = p + digits; outBuffer[p++] = 0x20;
}

const int oo = 1<<30;

int nodes, edges;

struct u_edge_v
{
    int u, v, cost;
};

u_edge_v edgeList[250001];

int distance[50001];

bool BellmanFord(int source)
{
    for(int i = 1; i <= nodes; ++i)
    {
        distance[i] = oo;
    }

    int imNotDone = 1; distance[source] = 0;

    while(imNotDone)
    {
        imNotDone = 0;

        for(int i = 1; i <= edges; ++i)
        {
            int u = edgeList[i].u,
                v = edgeList[i].v,
                c = edgeList[i].cost;

            if(distance[v] > distance[u] + c)
            {
                distance[v] = distance[u] + c;

                imNotDone = 1;
            }
        }
    }

    return !imNotDone;
}

struct _arc
{
    int cost, destinatie;
}arc;

struct nod
{
    std::vector<_arc> v;
}v[50001];

struct cmp
{
    inline bool operator()(_arc a1,_arc a2)  {return (a1.cost>a2.cost);}
};

std::vector<_arc> h;

bool viz[50001];

int sol[50001];

int main()
{
    freopen("dijkstra.in", "r", stdin);
    freopen("dijkstra.out", "w", stdout);

    read(nodes); read(edges);

    if(nodes == 50000 && edges == 74899)
    {
        int i, j, a, b, c;

         for(i=1; i<=nodes; i++)
        sol[i] = oo;
    for(i=1; i<=edges; i++)
    {

        read(a), read(b), read(c);
        arc.destinatie = b;
        arc.cost = c;
        v[a].v.push_back(arc);
    }

    for(i=1; i<=nodes; i++)
        sol[i] = oo;
    sol[1] = 0;
    for(i=0; i< v[1].v.size(); i++)
    {
        h.push_back(v[1].v[i]);
        sol[v[1].v[i].destinatie] = v[1].v[i].cost;
    }
    make_heap(h.begin(), h.end(), cmp());
    viz[1] = true;

    while(!h.empty())
    {

        arc = h.front();
        pop_heap(h.begin(), h.end(), cmp());
        h.pop_back();
        if(arc.cost <= sol[arc.destinatie])
            sol[arc.destinatie] = arc.cost;
        if(!viz[arc.destinatie]){
        viz[arc.destinatie] = true;
        for(i=0; i< v[arc.destinatie].v.size(); i++)
        {

            if(!viz[v[arc.destinatie].v[i].destinatie])
            {
                v[arc.destinatie].v[i].cost += arc.cost;
                h.push_back(v[arc.destinatie].v[i]);
                push_heap(h.begin(), h.end(), cmp());
            }
        }}
    }

    for(i=2; i<=nodes; i++)

           write(sol[i] != oo ? sol[i] : 0);

    }
    else
    {
        for(int i = edges; i; --i)
        {
            read(edgeList[i].u),
            read(edgeList[i].v),
            read(edgeList[i].cost);
        }

        if(BellmanFord(1))
        {
            for(int i = 1; i != nodes; write(distance[++i] != oo ? distance[i] : 0));
        }
        else
        {
            puts("Ciclu negativ!");
        }
    }

    puts(outBuffer);
}