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 }

 

posted @ 2018-07-23 22:45  MJT12044  阅读(219)  评论(0编辑  收藏  举报