1 /**
2 problem: http://www.fjutacm.com/Problem.jsp?pid=3700
3 按二进制将k个待查点分类分别跑dijkstra
4 **/
5 #include<stdio.h>
6 #include<vector>
7 #include<queue>
8 using namespace std;
9
10 const int MAXN = 505;
11 const int MAXM = 3e4+5;
12 const int INF = 0x3f3f3f3f;
13
14 int ans;
15
16 template <typename T>
17 class Graphics {
18 private:
19 struct Edge {
20 int to, next;
21 T w;
22 } edge[MAXM];
23 int first[MAXN], sign;
24 int sumOfPoint;
25 struct Node{
26 int to;
27 T w;
28 Node(int a, int b):to(a), w(b){}
29 Node(){}
30 bool friend operator < (const Node &a, const Node &b){
31 return a.w > b.w;
32 }
33 };
34 public:
35 void clear(int n) {
36 sumOfPoint = n;
37 for(int i = 1; i <= n; i ++) {
38 first[i] = -1;
39 }
40 sign = 0;
41 }
42 void addEdgeOneWay(int u, int v, int w) {
43 edge[sign].to = v;
44 edge[sign].w = w;
45 edge[sign].next = first[u];
46 first[u] = sign ++;
47 }
48 void addEdgeTwoWay(int u, int v, int w) {
49 addEdgeOneWay(u, v, w);
50 addEdgeOneWay(v, u, w);
51 }
52 vector<T> dijkstra(const vector<int> &start) {
53 vector<T> dist(sumOfPoint+1, INF);
54 vector<bool> visit(sumOfPoint+1);
55 priority_queue<Node> bfs;
56 for(unsigned i = 0; i < start.size(); i ++) {
57 bfs.push(Node(start[i], 0));
58 }
59 while(!bfs.empty()) {
60 Node now = bfs.top();
61 bfs.pop();
62 if(visit[now.to]) {
63 continue;
64 }
65 visit[now.to] = true;
66 dist[now.to] = now.w;
67 for(int i = first[now.to]; i != -1; i = edge[i].next) {
68 int to = edge[i].to, w = edge[i].w;
69 if(now.w + w > ans) continue; /// 剪枝 当最短路已经大于当前最优值也不用继续找了
70 if(!visit[to]) {
71 bfs.push(Node(to, now.w + w));
72 }
73 }
74 }
75 return dist;
76 }
77 };
78
79 class Solution {
80 private:
81 int n, m, u, v, w, k;
82 int kk[MAXN];
83 Graphics<int> graph;
84 public:
85 void solve() {
86 int t;
87 scanf("%d", &t);
88 while(t --) {
89 scanf("%d%d", &n, &m);
90 graph.clear(n);
91 while(m --) {
92 scanf("%d%d%d", &u, &v, &w);
93 graph.addEdgeOneWay(u, v, w);
94 }
95 scanf("%d", &k);
96 for(int i = 0; i < k; i ++) {
97 scanf("%d", &kk[i]);
98 }
99 ans = INF;
100 for(int i = 0; i < 10; i ++) {
101 vector<int> first, second;
102 for(int j = 0; j < k; j ++) {
103 if(kk[j] >> i & 1) {
104 first.push_back(kk[j]);
105 } else {
106 second.push_back(kk[j]);
107 }
108 }
109 vector<int> cur = graph.dijkstra(first);
110 for(unsigned j = 0; j < second.size(); j ++) {
111 ans = min(ans, cur[second[j]]);
112 }
113 cur = graph.dijkstra(second);
114 for(unsigned j = 0; j < first.size(); j ++){
115 ans = min(ans, cur[first[j]]);
116 }
117 }
118 printf("%d\n", ans);
119 }
120 }
121 } DarkScoCu;
122
123 int main() {
124 DarkScoCu.solve();
125 return 0;
126 }