#include #define ll long long using namespace std; const int MAXT = 2000; int N, M, G; ll F[205][205]; int P[205][205]; clock_t start, finish; int limit = 4.7 * CLOCKS_PER_SEC; int T; struct Moment { ll cost, idx; }C[205][2005], COST[205][2005]; struct Kid { int city, idx; }K[1005]; vector SOL[2005], TSOL[2005]; mt19937_64 rng; bool cmpM(Moment a, Moment b) { return a.cost < b.cost; } ll Score(vector V, int t) { ll ret = 0; ll sum = 0; int last = 1; for(Kid x : V) sum += COST[x.city][t].cost; for(Kid x : V) { ret += sum * F[last][x.city]; sum -= COST[x.city][t].cost; last = x.city; } return ret; } vector Reconstruct(int i, int j) { vector RET; if(i == j) return RET; while(i != j) { i = P[i][j]; RET.push_back(i); } return RET; } void FLOYD_WARSHALL() { for(int i = 1; i <= N; i++) F[i][i] = 0, P[i][i] = i; for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) if(F[i][j] != 1e9) P[i][j] = j; for(int k = 1; k <= N; k++) for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) if(F[i][k] + F[k][j] < F[i][j]) F[i][j] = F[i][k] + F[k][j], P[i][j] = P[i][k]; return; } void SOLVE() { FLOYD_WARSHALL(); ll scr = 0; ll tscr = 0; for(int i = 1; i <= N; i++) sort(C[i] + 1, C[i] + MAXT + 1, cmpM); for(int i = 1; i <= G; i++) for(int j = 1; j <= MAXT; j++) { if(TSOL[C[K[i].city][j].idx].size() >= 4) continue; TSOL[C[K[i].city][j].idx].push_back(K[i]); break; } for(int i = 1; i <= MAXT; i++) { if(!TSOL[i].size()) continue; tscr += Score(TSOL[i], i); for(Kid x : TSOL[i]) SOL[i].push_back(x); } scr = tscr; while(clock() - start <= limit) { tscr = 0; for(int i = 1; i <= MAXT; i++) TSOL[i].clear(); int a = rng() % G + 1; int b = rng() % G + 1; swap(K[a], K[b]); for(int i = 1; i <= G; i++) { ll best = 1e18; int bestT; vector Best; for(int j = 1; j <= MAXT; j++) { if(TSOL[C[K[i].city][j].idx].size() >= 4) continue; vector TEMP = TSOL[C[K[i].city][j].idx]; int idx = TEMP.size(); for(int k = 0; k < TEMP.size(); k++) if(K[i].city == TEMP[k].city) idx = k; TEMP.insert(TEMP.begin() + idx, K[i]); ll temp = Score(TEMP, C[K[i].city][j].idx); if(temp < best) { bestT = C[K[i].city][j].idx; Best = TEMP; best = temp; } vector cnt; for(Kid x : TEMP) cnt.push_back(x.city); if(count(cnt.begin(), cnt.end(), K[i].city) == cnt.size()) break; } TSOL[bestT] = Best; } for(int i = 1; i <= MAXT; i++) { if(!TSOL[i].size()) continue; tscr += Score(TSOL[i], i); } if(tscr <= scr) { scr = tscr; for(int i = 1; i <= MAXT; i++) { SOL[i].clear(); if(!TSOL[i].size()) continue; for(Kid x : TSOL[i]) SOL[i].push_back(x); } } else swap(K[a], K[b]); } for(int i = 1; i <= MAXT; i++) if(SOL[i].size()) T++; return; } void IN() { ios_base::sync_with_stdio(false); cin.tie(NULL); freopen("transport.in", "r", stdin); cin >> N >> M >> G; for(int i = 1; i <= G; i++) cin >> K[i].city, K[i].idx = i; for(int i = 1; i <= N; i++) for(int j = 1; j <= MAXT; j++) cin >> C[i][j].cost, C[i][j].idx = COST[i][j].idx = j, COST[i][j].cost = C[i][j].cost; for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) F[i][j] = 1e9; for(int i = 1; i <= M; i++) { int u, v, w; cin >> u >> v >> w; F[u][v] = w; F[v][u] = w; } return; } void OUT() { freopen("transport.out", "w", stdout); cout << T << "\n"; for(int i = 1; i <= MAXT; i++) { if(!SOL[i].size()) continue; vector PATH; int last = 1; PATH.push_back(1); for(Kid x : SOL[i]) { vector path = Reconstruct(last, x.city); last = x.city; for(int y : path) PATH.push_back(y); } cout << i << " " << SOL[i].size() << " " << PATH.size() << "\n"; for(Kid x : SOL[i]) cout << x.idx << " "; cout << "\n"; for(int x : PATH) cout << x << " "; cout << "\n"; } return; } int main() { IN(); SOLVE(); OUT(); return 0; }