Cod sursa(job #3331771)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 30 decembrie 2025 21:07:22
Problema Algoritmul lui Dijkstra Scor 20
Compilator c-64 Status done
Runda Arhiva educationala Marime 4.76 kb
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>

typedef long long i64;
#define UNUSED -1
#define inf 1000000000
#define N_MAX 300000
#define M_MAX 300000
#define K_MAX 300000
const i64 INF = 1e18;

void swap(void *a, void* b, size_t size)
{
    uint8_t aux[size];
    memcpy(aux, a, size);
    memcpy(a, b, size);
    memcpy(b, aux, size);
}
//////////////////////////////////
typedef struct {
    int from, to, dist;
    i64 final_distance;
} edge;
int n, m, k, source, destination;
int **adj, *adj_size;
edge *edges;
/////////////////////////////////
//////////step 1/////////////////
//We are doing the first dijkstra from the destination node
typedef struct {
    i64 value;
    int index;
} heap_node_1;

//verifys if the first is better then the second
bool better(heap_node_1 a, heap_node_1 b)
{
    return a.value <= b.value;
}
int heap_1_sz = 0;
heap_node_1 *heap_1;
i64 *dist_init;
int *best_edge;
int left_child(int x)
{
    return 2 * x;
}

int right_child(int x)
{
    return 2 * x + 1;
}

int parent(int x)
{
    return x / 2;
}

void push_up_1(int poz)
{
    while (poz > 1 && better(heap_1[poz], heap_1[parent(poz)]))
    {
        swap(&heap_1[poz], &heap_1[parent(poz)], sizeof(heap_node_1));
        poz = parent(poz);
    }
}
void push_down_1(int poz)
{
    while (right_child(poz) <= heap_1_sz && (better(heap_1[left_child(poz)], heap_1[poz]) ||
                                             better(heap_1[right_child(poz)], heap_1[poz])))
    {
        if (better(heap_1[left_child(poz)], heap_1[right_child(poz)]))
        {
            swap(&heap_1[poz], &heap_1[left_child(poz)], sizeof(heap_node_1));
            poz = left_child(poz);
        }
        else
        {
            swap(&heap_1[poz], &heap_1[right_child(poz)], sizeof(heap_node_1));
            poz = right_child(poz);
        }
    }
    if (left_child(poz) <= heap_1_sz && better(heap_1[left_child(poz)], heap_1[poz]))
    {
        swap(&heap_1[poz], &heap_1[left_child(poz)], sizeof(heap_node_1));
    }
}

void heap_1_add(i64 val, int index)
{
    heap_1_sz++;
    heap_1[heap_1_sz].value = val;
    heap_1[heap_1_sz].index = index;
    push_up_1(heap_1_sz);
}

heap_node_1 heap_1_min()
{
    assert(heap_1_sz > 0);
    return heap_1[1];
}

void heap_1_pop()
{
    heap_1[1] = heap_1[heap_1_sz];
    heap_1_sz--;
    push_down_1(1);
}

void dijkstra()
{
    for (int i = 0; i < n; i ++)
    {
        dist_init[i] = INF;
        best_edge[i] = UNUSED;
    }
    dist_init[destination] = 0;
    heap_1_add(0, destination);
    while (heap_1_sz > 0)
    {
        int from = heap_1_min().index;
        i64 dist_from = heap_1_min().value;
        heap_1_pop();
        if (dist_init[from] != dist_from)
        {
            continue;
        }
        for (int i = 0; i < adj_size[from]; i++)
        {
            int ind_edge = adj[from][i];
            int to = edges[ind_edge].to;
            int weight = edges[ind_edge].dist;
            if (dist_init[to] > dist_from + weight)
            {
                dist_init[to] = dist_from + weight;
                best_edge[to] = ind_edge;
                heap_1_add(dist_init[to], to);
            }
        }
    }
    for (int i = 1; i < n; i++)
    {
        printf("%lld ", dist_init[i]);
    }
}
/////////////////////////////////////
///
///
void read_graph()
{
    edges = (edge *) malloc(m * sizeof(edge));
    adj = (int **) malloc(n * sizeof(int *));
    adj_size = (int *) malloc(n * sizeof(int));
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d%d", &edges[i].from, &edges[i].to, &edges[i].dist);
        edges[i].from--;
        edges[i].to--;
        adj_size[edges[i].from]++;
    }
    for (int i = 0; i < n; i++)
    {
        if (adj_size[i] > 0)
        {
            adj[i] = (int *)malloc(adj_size[i] * sizeof(int));
            adj_size[i] = 0;
        }
    }
    for (int i = 0; i < m; i++)
    {
        int from = edges[i].from;
        adj[from][adj_size[from]++] = i;
    }
}

void read_data()
{
    // scanf("%d%d%d%d%d", &n, &m, &source, &destination, &k);
    scanf("%d%d", &n, &m);
    // printf("x%dx", n);
    destination = 1;
    source--;
    destination--;
    heap_1 = (heap_node_1 *) malloc((n + 1) * sizeof(heap_node_1));
    best_edge = (int *) malloc(n * sizeof(int));
    dist_init = (i64 *) malloc(n * sizeof(i64));
    read_graph();
}

void free_data()
{
    for (int i = 0; i < n; i++)
    {
        if (adj_size[i] > 0)
        {
            free(adj[i]);
        }
    }
    free(adj);
    free(adj_size);
    free(edges);
    free(heap_1);
    free(best_edge);
    free(dist_init);
}

int main(void)
{
    // setbuf(stdout, NULL);
    freopen("dijkstra.in", "r", stdin);
    freopen("dijkstra.out", "w", stdout);
    read_data();
    dijkstra();
    free_data();
    return 0;
}