1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| #include <bits/stdc++.h> using namespace std; using ll = long long;
const int maxn = 200 + 50; const int maxp = 13; const int inf = 1e9;
struct Edge { int to, time, need; }; struct Node { int d, u, mask; bool operator < ( const Node &a ) const { return d > a.d; } };
int dist[maxn][ 1 << maxp ]; int sword[maxn]; vector< Edge > adj[maxn]; int n, m, p, k;
void dijkstra( ) { memset( dist, 127, sizeof( dist ) ); priority_queue< Node > pq;
int start_mask = sword[1]; dist[1][start_mask] = 0; pq.push({ 0, 1, start_mask }); while( !pq.empty( ) ) { auto [d, u, mask] = pq.top( ); pq.pop( );
if( d > dist[u][mask] ) continue;
for( auto [v, t, need] : adj[u] ) { if( ( mask & need ) != need ) continue; int next_mask = mask | sword[v]; if( dist[v][next_mask] > d + t ) { dist[v][next_mask] = d + t; pq.push({ dist[v][next_mask], v, next_mask }); } } } }
void solve( ) { cin >> n >> m >> p >> k;
for( int i = 1; i <= k; ++ i ) { int w, q, r, mask = 0; cin >> w >> q; while( q -- ) { cin >> r; mask |= ( 1 << (r - 1) ); } sword[w] |= mask; }
for( int i = 1; i <= m; ++ i ) { int v, w, t, s, u, mask = 0; cin >> v >> w >> t >> s; while( s -- ) { cin >> u; mask |= ( 1 << (u - 1) ); } adj[v].push_back({ w, t, mask }); adj[w].push_back({ v, t, mask }); }
dijkstra( );
int ans = inf;
for( int mask = 0; mask < (1 << p); ++ mask ) ans = min( ans, dist[n][mask] );
if( ans == inf ) cout << -1 << '\n'; else cout << ans << '\n'; }
int main( ) { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); solve( ); return 0; }
|