#include #include #include #include #include using namespace std; int n, m, g; vector> orig[200]; vector> adj1[200]; vector decaotgrad1[200]; vector decaotgradorig[200]; int mini; long long price[4000], minn = -1; int cost[200][2000]; fstream cinn, coutt; int dist[200]; int stupka; int moment = 1, minmom = 1; struct otgovor { int r, k, h; vector deca, grada; }; vector ans[4000]; void djikstra(int krai, int br) { int p[200]; p[0] = -1; fill_n(dist, n, INT_MAX); dist[0] = 0; priority_queue> q; q.push({ 0,0 }); while (!q.empty()) { auto cur = q.top(); q.pop(); if (dist[cur.second] >= -cur.first) { for (auto a : adj1[cur.second]) { int to = a.first, dulj = a.second; if (dist[to] >= dist[cur.second] + dulj) { p[to] = cur.second; dist[to] = dist[cur.second] + dulj; if (to != krai) q.push({ -dist[to],to }); } } } } price[(minmom - 1) / stupka] += (long long)br * cost[krai][moment - 1] * dist[krai]; otgovor otg = { moment,br,0 }; int v = krai; while (v > -1) { otg.grada.emplace(otg.grada.begin(), v); v = p[v]; otg.h++; } while (br--) { otg.deca.emplace_back(decaotgrad1[krai].back()); decaotgrad1[krai].pop_back(); } ans[(minmom - 1) / stupka].push_back(otg); } void djikstra2(int krai) { int p[200]; p[0] = -1; fill_n(dist, n, INT_MAX); dist[0] = 0; priority_queue> q; q.push({ 0,0 }); while (!q.empty()) { auto cur = q.top(); q.pop(); if (dist[cur.second] >= -cur.first) { for (auto a : adj1[cur.second]) { int to = a.first, dulj = a.second; if (dist[to] >= dist[cur.second] + dulj) { p[to] = cur.second; dist[to] = dist[cur.second] + dulj; if (to != krai) q.push({ -dist[to],to }); } } } } otgovor otg = { moment,0,0 }; int v = krai; while (v > -1) { otg.grada.emplace(otg.grada.begin(), v); if (decaotgrad1[v].size() > 0 && otg.k < 4) { otg.k++; otg.deca.emplace_back(decaotgrad1[v].back()); decaotgrad1[v].pop_back(); price[(minmom - 1) / stupka] += (long long)dist[v] * cost[v][moment - 1]; } v = p[v]; otg.h++; } ans[(minmom - 1) / stupka].push_back(otg); } // void djikstra1(int krai, int br) { int p[200]; p[0] = -1; fill_n(dist, n, INT_MAX); dist[0] = 0; priority_queue> q; q.push({ 0,0 }); while (!q.empty()) { auto cur = q.top(); q.pop(); if (dist[cur.second] >= -cur.first) { for (auto a : adj1[cur.second]) { int to = a.first, dulj = a.second; if (dist[to] >= dist[cur.second] + dulj) { p[to] = cur.second; dist[to] = dist[cur.second] + dulj; if (to != krai) q.push({ -dist[to],to }); } } } } price[((minmom - 1) / stupka) * 2] += (long long)br * cost[krai][moment - 1] * dist[krai]; otgovor otg = { moment,br,0 }; int v = krai; while (v > -1) { otg.grada.emplace(otg.grada.begin(), v); v = p[v]; otg.h++; } while (br--) { otg.deca.emplace_back(decaotgrad1[krai].back()); decaotgrad1[krai].pop_back(); } ans[((minmom - 1) / stupka) * 2].push_back(otg); } void djikstra12(int krai) { int p[200]; p[0] = -1; fill_n(dist, n, INT_MAX); dist[0] = 0; priority_queue> q; q.push({ 0,0 }); while (!q.empty()) { auto cur = q.top(); q.pop(); if (dist[cur.second] >= -cur.first) { for (auto a : adj1[cur.second]) { int to = a.first, dulj = a.second; if (dist[to] >= dist[cur.second] + dulj) { p[to] = cur.second; dist[to] = dist[cur.second] + dulj; if (to != krai) q.push({ -dist[to],to }); } } } } otgovor otg = { moment,0,0 }; int v = krai; while (v > -1) { otg.grada.emplace(otg.grada.begin(), v); if (decaotgrad1[v].size() > 0 && otg.k < 4) { otg.k++; otg.deca.emplace_back(decaotgrad1[v].back()); decaotgrad1[v].pop_back(); price[((minmom - 1) / stupka) * 2] += (long long)dist[v] * cost[v][moment - 1]; } v = p[v]; otg.h++; } ans[((minmom - 1) / stupka) * 2].push_back(otg); } // int main() { ios_base::sync_with_stdio(false); cinn.open("transport.in", ios_base::in); coutt.open("transport.out", ios_base::out); cinn.tie(0); coutt.tie(0); cinn >> n >> m >> g; if (n < 100)stupka = 1; else stupka = 5; int a, b, d, grad; for (int i = 0; i < g; i++) { cinn >> grad; decaotgrad1[grad - 1].emplace_back(i); decaotgradorig[grad - 1].emplace_back(i); } for (int i = 0; i < n; i++) { for (int ii = 0; ii < 2000; ii++) { cinn >> cost[i][ii]; } } for (int i = 0; i < m; i++) { cinn >> a >> b >> d; adj1[a - 1].push_back({ b - 1,d }); adj1[b - 1].push_back({ a - 1,d }); orig[a - 1].push_back({ b - 1,d }); orig[b - 1].push_back({ a - 1,d }); } // djikstra(); while (minmom <= 2000 - (mini > -1 ? ans[mini].size() : n)) { moment = minmom; for (int i = 0; i < n; i++) { decaotgrad1[i] = decaotgradorig[i]; adj1[i] = orig[i]; } while (true) { bool bb = false; for (int i = 1; i < n; i++) { if (decaotgrad1[i].size() > 1) { bb = true; moment = moment + 1; djikstra(i, min((int)decaotgrad1[i].size(), 4)); } } if (!bb) break; } while (true) { bool bb = false; for (int i = 1; i < n; i++) { if (decaotgrad1[i].size() > 0) { bb = true; moment = moment + 1; djikstra2(i); } } if (!bb) break; } while (true) { bool bb = false; if (decaotgrad1[0].size() > 0) { bb = true; moment = moment + 1; int br = min(4, (int)decaotgrad1[0].size()); otgovor otg = { moment,br,1 }; otg.grada.emplace_back(0); while (br--) { otg.deca.emplace_back(decaotgrad1[0].back()); decaotgrad1[0].pop_back(); } ans[(minmom - 1) / stupka].push_back(otg); } if (!bb) break; } if (price[(minmom - 1) / stupka] < minn || minn == -1) { mini = (minmom - 1) / stupka; minn = price[(minmom - 1) / stupka]; } /// if (minmom > 1400) continue; moment = minmom; for (int i = 0; i < n; i++) { decaotgrad1[i] = decaotgradorig[i]; adj1[i] = orig[i]; } while (true) { bool bb = false; for (int i = 1; i < n; i++) { if (decaotgrad1[i].size() > 1) { bb = true; moment = moment + 2; djikstra1(i, min((int)decaotgrad1[i].size(), 4)); } } if (!bb) break; } while (true) { bool bb = false; for (int i = 1; i < n; i++) { if (decaotgrad1[i].size() > 0) { bb = true; moment = moment + 2; djikstra12(i); } } if (!bb) break; } while (true) { bool bb = false; if (decaotgrad1[0].size() > 0) { bb = true; moment = moment + 1; int br = min(4, (int)decaotgrad1[0].size()); otgovor otg = { moment,br,1 }; otg.grada.emplace_back(0); while (br--) { otg.deca.emplace_back(decaotgrad1[0].back()); decaotgrad1[0].pop_back(); } ans[((minmom - 1) / stupka) * 2].push_back(otg); } if (!bb) break; } if (price[((minmom - 1) / stupka) * 2] < minn || minn == -1) { mini = (minmom - 1) / stupka; minn = price[((minmom - 1) / stupka) * 2]; } minmom = minmom + stupka; } coutt << ans[mini].size() << "\n"; for (auto a : ans[mini]) { coutt << a.r << " " << a.k << " " << a.h << "\n"; for (int d : a.deca) coutt << d + 1 << " "; coutt << "\n"; for (int d : a.grada) coutt << d + 1 << " "; coutt << "\n"; } }