#include #include #include #include #include using namespace std; const int INFINITY = 1000000000; const int MAXN = 100000; int n, m, k, f, ci, x, y, node[MAXN], parent[MAXN], order[MAXN]; int path[MAXN]; int answer[MAXN], answerSize; int weight[MAXN], dist[MAXN]; vector > adj[MAXN]; set > S; void readInput () { cin >> n >> m >> k >> f; for(int i = 1; i <= k; i++) { cin >> ci >> weight[i]; int minCost = INFINITY; for(int j = 0; j < ci; j++) { cin >> x >> y; if (y < minCost) { minCost = y; node[i] = x; } } } for(int i = 1; i <= m; i++) { int x, y, z; cin >> x >> y >> z; adj[x].push_back(make_pair(y, z)); adj[y].push_back(make_pair(x, z)); } } void relax (int vn, int vd, int par) { if (dist[vn] <= vd) return ; pair o = make_pair(dist[vn], vn); if (S.find(o) != S.end()) S.erase(S.find(o)); dist[vn] = vd; o = make_pair(dist[vn], vn); S.insert(o); parent[vn] = par; } void constructPath (int nodeFrom, int nodeTo) { if (nodeFrom == nodeTo) return ; for(int i = 1; i <= n; i++) dist[i] = INFINITY; S.clear(); relax(nodeFrom, 0, -1); while (S.size()) { int nodeNumber = S.begin()->second; S.erase(S.begin()); for(int j = 0; j < adj[nodeNumber].size(); j++) { relax(adj[nodeNumber][j].first, dist[nodeNumber] + adj[nodeNumber][j].second, nodeNumber); } } int pathLength = 0; while (nodeTo != nodeFrom) { path[++pathLength] = nodeTo; nodeTo = parent[nodeTo]; } reverse(path + 1, path + pathLength + 1); for(int i = 1; i <= pathLength; i++) answer[++answerSize] = path[i]; } void writeOutput () { printf("%d\n", answerSize); for(int i = 1; i < answerSize; i++) printf("%d ", answer[i]); printf("%d\n", answer[answerSize]); } int main(int argc, const char * argv[]) { ios_base::sync_with_stdio(false); readInput(); for(int i = 1; i <= k; i++) order[i] = i; int currentNode = 1; for(int i = 1; i <= k; i++) { constructPath(currentNode, node[order[i]]); answer[++answerSize] = -order[i]; currentNode = node[order[i]]; } constructPath(currentNode, n); writeOutput(); return 0; }