Cod sursa(job #1522386)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 11 noiembrie 2015 17:24:22
Problema Ciclu hamiltonian de cost minim Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <cstdio>
#include <algorithm>
#include <cstring>

using std::min;

const int MAX_N = 18;
const int MAX_M = MAX_N * (MAX_N - 1);
const int NIL = -1;
const int INF = 0x3F3F3F3F;

struct Edge {
    int v, next;
};

Edge l[MAX_M];
int adj[MAX_N];

int d[1 << MAX_N][MAX_N];
int cost[MAX_N][MAX_N];

void addEdge(int u, int v, int pos) {
    l[pos].v = v;
    l[pos].next = adj[u];
    adj[u] =  pos;
}

int main(void) {
    freopen("hamilton.in", "r", stdin);
    freopen("hamilton.out", "w", stdout);
    int n, m;
    int u, v, q;

    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        adj[i] = NIL;
    }
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &q);
        cost[u][v] = q;
        addEdge(u, v, i);
    }
    fclose(stdin);

    for (int i = 1; i < (1 << n); i++) {
        if (i & (i - 1)) {
            memset(d[i], INF, sizeof(d[i]));
        } else {
            d[i][31 - __builtin_clz(i)] = 0;
        }
    }

    for (int i = 1; i < (1 << n); i++) {
        for (int j = 0; j < n; j++) {
            if (((i >> j) & 1) && (d[i][j] != INF)) {
                for (int u = adj[j]; u != NIL; u = l[u].next) {
                    int v = l[u].v;
                    if (!((i >> v) & 1)) {
                        d[i ^ (1 << v)][v] = min(d[i ^ (1 << v)][v], d[i][j] + cost[j][v]);
                    }
                }
            }
        }
    }
    q = INF;
    for (int i = 0; i < n; i++) {
        if (cost[i][0]) {
            q = min(q, d[(1 << n) - 1][i] + cost[i][0]);
        }
    }
    if (q != INF) {
        printf("%d\n", q);
    } else {
        puts("Nu exista solutie");
    }
    fclose(stdout);
    return 0;
}