Cod sursa(job #1857802)

Utilizator yosemiteYosemite yosemite Data 26 ianuarie 2017 18:14:35
Problema Gather Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("gather.in");
ofstream g("gather.out");
const int bMax = 16;
const int nMax = 766;
const long long inf = (1LL << 56);
vector <int> Graf[nMax];
long long det[nMax], cost[nMax][nMax], maxdet[nMax][nMax], dp[nMax], dist[bMax][bMax][bMax];
long long dpans[(1 << bMax)][bMax];
long long n , m , k;
struct cmp{
    inline bool operator () (const int &x, const int &y) {
        return dp[x] > dp[y];
    }
};
priority_queue <int, vector<int> ,cmp> Q;
inline void Dij(int start, int detmin) { ///distanta minima de la nodul det[start] la nodul det[i] trecand prin muchii cu capacitatea cel putin detmin
    for(int i = 0; i <= n; i++) {
        dp[i] = inf;
    }
    dp[det[start]] = 0;
    Q.push(det[start]);
    while(!Q.empty()) {
        int node = Q.top();
        Q.pop();
        for(auto i : Graf[node]) {
            if(maxdet[node][i] >= detmin && dp[node] + cost[node][i] < dp[i]) {
                dp[i] = dp[node] + cost[node][i];
                Q.push(i);
            }
        }
    }
    for(int i = 0; i <= k; i++) {
        dist[start][detmin][i] = dp[det[i]]; ///de la det[start] la det[i]
    }
}
inline int Cntbits(int number) {
    int cnt = 0;
    for(int i = 0; i < bMax;i++) {
        if(number & (1 << i)) {
            cnt++;
        }
    }
    return cnt;
}
inline void Solve_biti() {
    int maxB = (1 << k) - 1;
    for(int i = 0; i < (1 << k); i++) {
        for(int j = 0; j <= k; j++) {
            dpans[i][j] = inf;
        }
    }
    dpans[0][k] = 0; ///dp i , j - costul minim de a ajunge la nodul i cu j prizonieri din conf
    for(int conf = 0; conf <= maxB; conf++) { /// iau fiecare configuratie binara
        for(int i = 0; i < k; i++) { ///vreau la i
            if(conf & (1 << i)) {
                for(int j = 1; j <= k; j++) { ///la nodul j
                    if(j != i) {
                        int cntprison = Cntbits(conf - (1 << i));
                        dpans[conf][i] = min(dpans[conf][i], dpans[conf - (1 << i)][j] + dist[j][cntprison][i] * (cntprison + 1));
                    }

                }
            }
        }
    }
    long long ans = inf;
    for(int i = 0; i < k; i++) {
        //g << dpans[conf][i] << " ";
        ans = min(ans,dpans[maxB][i]);
    }
    g << ans << "\n";
}
int main()
{
    int x, y, c, d;
    f >> k >> n >> m;
    for(int i = 0; i < k; i++) {
        f >> det[i];
    }
    for(int i = 1; i <= m; i++) {
        f >> x >> y >> c >> d;
        Graf[x].push_back(y);
        Graf[y].push_back(x);
        cost[x][y] = cost[y][x] = c;
        maxdet[x][y] = maxdet[y][x] = d;
    }
    det[k] = 1; ///gigel e k
    for(int i = 0; i <= k; i++) {
        for(int j = 0; j <= k; j++) {
            Dij(i,j); ///de la detinutul det[i] pe muchii cu cel putin j
        }
    }
    Solve_biti();
    return 0;
}