Cod sursa(job #2877117)

Utilizator rapidu36Victor Manz rapidu36 Data 24 martie 2022 09:56:32
Problema Ciclu hamiltonian de cost minim Scor 50
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <stdio.h>
#include <stdlib.h>
#define N 18
#define INF (1 << 27)

int n, c[N][N], dp[1<<N][N], pred[1<<N][N];

void extinde(int multime, int vf)
{
    for (int j = 0; j < n; j++)
    {
        if (c[vf][j] != INF && (multime & (1 << j)) == 0)
        {
            int multime_noua = (multime | (1 << j));
            if (dp[multime][vf] + c[vf][j] < dp[multime_noua][j])
            {
                dp[multime_noua][j] = dp[multime][vf] + c[vf][j];
                pred[multime_noua][j] = multime;
            }
        }
    }
}

int main()
{
    FILE *in, *out;
    in = fopen("hamilton.in", "r");
    out = fopen("hamilton.out", "w");
    int m;
    fscanf(in, "%d%d", &n, &m);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            c[i][j] = INF;
        }
        c[i][i] = 0;
    }
    for (int i = 0; i < m; i++)
    {
        int x, y, cost;
        fscanf(in, "%d%d%d", &x, &y, &cost);
        c[x][y] = cost;
    }
    for (int i = 1; i < (1 << n); i++)
    {
        for (int j = 0; j < n; j++)
        {
            dp[i][j] = INF;
        }
    }
    dp[1][0] = 0;///drumul de la 0 la 0 care contine doar 0 are constul 0

    for (int i = 1; i < (1 << n); i += 2)
    {
        for (int j = 0; j < n; j++)
        {
            if (dp[i][j] != INF)///exista drum cu varfurile i, terminat cu j
            {
                extinde(i, j);
            }
        }
    }

    int rez = INF, toti = (1 << n) - 1;
    for (int j = 1; j < n; j++)
    {
        if (dp[toti][j] + c[j][0] < rez)
        {
            rez = dp[toti][j] + c[j][0];
        }
    }
    fprintf(out, "%d\n", rez);
    fclose(in);
    fclose(out);
    return 0;
}