#include #include #include #include #define INF 99999999 using namespace std; typedef int weight; typedef vector arr; typedef vector matrix; weight minimum_steiner_tree(const vector& T, const matrix &g) { const int n = g.size(); const int numT = T.size(); if (numT <= 1) return 0; matrix d(g); // all-pair shortest for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) d[i][j] = min( d[i][j], d[i][k] + d[k][j] ); weight OPT[(1 << numT)][n]; for (int S = 0; S < (1 << numT); ++S) for (int x = 0; x < n; ++x) OPT[S][x] = INF; for (int p = 0; p < numT; ++p) // trivial case for (int q = 0; q < n; ++q) OPT[1 << p][q] = d[T[p]][q]; for (int S = 1; S < (1 << numT); ++S) { // DP step if (!(S & (S-1))) continue; for (int p = 0; p < n; ++p) for (int E = 0; E < S; ++E) if ((E | S) == S) OPT[S][p] = min( OPT[S][p], OPT[E][p] + OPT[S-E][p] ); for (int p = 0; p < n; ++p) for (int q = 0; q < n; ++q) OPT[S][p] = min( OPT[S][p], OPT[S][q] + d[p][q] ); } weight ans = INF; for (int S = 0; S < (1 << numT); ++S) for (int q = 0; q < n; ++q) ans = min(ans, OPT[S][q] + OPT[((1 << numT)-1)-S][q]); return ans; } int main(){ int N,M,T; unordered_map>>m; scanf("%d%d%d",&N,&M,&T); for(int i=0;iv(T); for(int i=0;i