首先预处理出来前K个点互相之间的最短路,直接Dijkstra就好了
然后就变成了状压DP。。。随便写一下好了
1 /************************************************************** 2 Problem: 1097 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:18456 ms 7 Memory:98872 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 #include <queue> 14 15 using namespace std; 16 const int N = 2e4 + 5; 17 const int M = 2e5 + 5; 18 const int K = 22; 19 const int Tot_S = 1 << 20; 20 const int inf = 1e9; 21 22 struct edge { 23 int next, to, v; 24 edge(int _n = 0, int _t = 0, int _v = 0) : next(_n), to(_t), v(_v) {} 25 } e[M << 1]; 26 27 struct heap_node { 28 int v, to; 29 heap_node(int _v = 0, int _t = 0) : v(_v), to(_t) {} 30 31 inline bool operator < (const heap_node &p) const { 32 return v > p.v; 33 } 34 }; 35 36 int n, m, k, ans; 37 int first[N], tot; 38 int bin[K], a[K]; 39 int dis[K][K], d[N]; 40 int S, S1; 41 int f[Tot_S][K]; 42 priority_queue <heap_node> h; 43 44 inline int read() { 45 static int x; 46 static char ch; 47 x = 0, ch = getchar(); 48 while (ch < '0' || '9' < ch) 49 ch = getchar(); 50 while ('0' <= ch && ch <= '9') { 51 x = x * 10 + ch - '0'; 52 ch = getchar(); 53 } 54 return x; 55 } 56 57 inline void Add_Edges(int x, int y, int z) { 58 e[++tot] = edge(first[x], y, z), first[x] = tot; 59 e[++tot] = edge(first[y], x, z), first[y] = tot; 60 } 61 62 inline void add_to_heap(int p) { 63 static int x; 64 for (x = first[p]; x; x = e[x].next) 65 if (d[e[x].to] == -1) 66 h.push(heap_node(e[x].v + d[p], e[x].to)); 67 } 68 69 void Dijkstra(int S) { 70 static int p; 71 memset(d, -1, sizeof(d)); 72 while (!h.empty()) h.pop(); 73 d[S] = 0, add_to_heap(S); 74 while (!h.empty()) { 75 if (d[h.top().to] != -1) { 76 h.pop(); 77 continue; 78 } 79 p = h.top().to; 80 d[p] = h.top().v; 81 h.pop(); 82 add_to_heap(p); 83 } 84 } 85 86 int main() { 87 int i, j, x, y, z; 88 n = read(), m = read(), k = read(); 89 for (i = 1; i <= m; ++i) { 90 x = read(), y = read(), z = read(); 91 Add_Edges(x, y, z); 92 } 93 for (i = 1; i <= k + 1; ++i) { 94 Dijkstra(i); 95 for (dis[i][0] = d[n], j = 1; j <= k + 1; ++j) 96 dis[i][j] = d[j]; 97 } 98 for (i = bin[0] = 1; i <= k + 1; ++i) bin[i] = bin[i - 1] << 1; 99 for (x = read(), i = 1; i <= x; ++i) 100 y = read(), z = read(), a[z] += bin[y - 2]; 101 102 memset(f, 0x3f, sizeof(f)); 103 for (S = f[0][1] = 0; S < bin[k]; ++S) 104 for (i = 1; i <= k + 1; ++i) if (f[S][i] != 0x3f3f3f3f) 105 for (j = 2; j <= k + 1; ++j) { 106 S1 = S | bin[j - 2]; 107 if ((S & a[j]) == a[j]) f[S1][j] = min(f[S1][j], f[S][i] + dis[i][j]); 108 } 109 for (ans = inf, i = 1; i <= k + 1; ++i) 110 ans = min(ans, f[bin[k] - 1][i] + dis[i][0]); 111 printf("%d\n", ans); 112 return 0; 113 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen