1139: [POI2009]Wie
1139: [POI2009]Wie
https://www.lydsy.com/JudgeOnline/problem.php?id=1139
分析:
Dijkstra。状压最短路,dis[i][j]表示到第i个点,状态为j的最短路。
或者 分层最短路可以做。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 5 inline int read() { 6 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 7 for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 8 } 9 10 const int N = 210; 11 const int M = 3010; 12 13 int dis[210][8200], head[N], to[M<<1], nxt[M<<1], sta[M<<1], len[M<<1], S[N], Enum, n; 14 bool vis[210][8200]; 15 16 struct Heap{ 17 int u, dis, st; 18 Heap() {} 19 Heap(int a,int b,int c) {u = a, dis = b, st = c;} 20 bool operator < (const Heap &A) const { 21 return dis > A.dis; 22 } 23 }; 24 priority_queue < Heap > q; 25 26 void add_edge(int u,int v,int w,int s) { 27 ++Enum; to[Enum] = v; len[Enum] = w; sta[Enum] = s; nxt[Enum] = head[u]; head[u] = Enum; 28 ++Enum; to[Enum] = u; len[Enum] = w; sta[Enum] = s; nxt[Enum] = head[v]; head[v] = Enum; 29 } 30 31 int Dijkstra() { 32 memset(dis, 0x3f, sizeof(dis)); 33 dis[1][0] = 0; 34 q.push(Heap(1, 0, 0)); 35 while (!q.empty()) { 36 int d = q.top().dis, u = q.top().u, s = q.top().st; q.pop(); 37 if (u == n) return d; 38 if (vis[u][s]) continue; 39 vis[u][s] = true; 40 s |= S[u]; 41 for (int i=head[u]; i; i=nxt[i]) { 42 int v= to[i]; 43 if ((sta[i] | s) != s) continue; 44 if (dis[v][s] > d + len[i]) { 45 dis[v][s] = d + len[i]; 46 q.push(Heap(v, dis[v][s], s)); 47 } 48 } 49 } 50 return -1; 51 } 52 53 int main () { 54 55 n = read(); int m = read(), p = read(), k = read(); 56 for (int w,cnt,t,st,i=1; i<=k; ++i) { 57 w = read(), cnt = read(); 58 for (int j=1; j<=cnt; ++j) { 59 t = read(); 60 S[w] |= (1 << (t - 1)); 61 } 62 } 63 for (int i=1; i<=m; ++i) { 64 int u = read(), v = read(), w = read(), cnt = read(), st = 0, t; 65 for (int j=1; j<=cnt; ++j) { 66 t = read(); 67 st |= (1 << (t - 1)); 68 } 69 add_edge(u, v, w, st); 70 } 71 printf("%d",Dijkstra()); 72 return 0; 73 }