Cod sursa(job #2305081)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 19 decembrie 2018 01:08:19
Problema Team Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <bits/stdc++.h>

class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}

	InParser& operator >> (long long &n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};

#define int_pair std::pair <int, int>

#define MAXN 505
#define MAXP 55
#define inf  1000000005

int N, M, P;
int Dest[MAXP];
std::vector <int_pair> ADC[MAXN];

inline void AddEdge(int x, int y, int w) {
    ADC[x].push_back({y, w});
    ADC[y].push_back({x, w});
}

InParser      In("team.in");
std::ofstream Out("team.out");

std::priority_queue <int_pair> PQ;
int Dist[MAXP][MAXN];
int DP[MAXP][MAXP][MAXP];

void Dijkstra(int src, int D[]) {
    for (int i=1; i<=N; ++i)
        D[i] = inf;
    D[src] = 0;
    PQ.push({0, src});

    int_pair Top;
    while (!PQ.empty()) {
        Top = PQ.top();
        PQ.pop();

        if (Top.first > D[Top.second]) continue;
        for (auto Edge:ADC[Top.second])
            if (D[Edge.first] > Top.first + Edge.second)
                D[Edge.first] = Top.first + Edge.second,
                PQ.push({D[Edge.first], Edge.first});
    }
}

void Citire() {
    In >> P >> N >> M;
    for (int i=0, x, y, w; i<M; ++i)
        In >> x >> y >> w, AddEdge(x, y, w);
    for (int i=1; i<=P; ++i)
        In >> Dest[i];
}

void Rezolvare() {
    Dest[0] = 1;
    for (int i=0; i<=P; ++i)
        Dijkstra(Dest[i], Dist[i]);

    for (int i=0, j, k; i<=P; ++i)
        for (j=0; j<=P; ++j)
            if (i<=j) for (k=0; k<=P; ++k)
                DP[i][j][k] = inf;

    for (int len=1, i, j, k; len<=P; ++len)
        for (i=1; (i+len-1)<=P; ++i)
            for (j=0; j<=P; ++j) {
                if (len == 1 && i == j) {
                    DP[i][i][i] = 0;
                    continue;
                }

                for (k=i; k<=(i+len-1); ++k)
                    DP[i][i+len-1][j] = std::min(DP[i][i+len-1][j], DP[i][k-1][k] + DP[k+1][i+len-1][k] + Dist[j][Dest[k]]);
            }   Out << DP[1][P][0] << '\n';
}

int main()
{
    Citire();
    Rezolvare();

    return 0;
}