http://acm.hdu.edu.cn/showproblem.php?pid=6166
枚举二进制位,则必存在 (j) 使得 (ansS&(1<<j) e ansT&(1<<j))
即答案的起点 (S) 和 (T) 被 (1<<j) 分至两个集合里,问题就变成求多起点多终点的最短路问题
- 有向图需要计算 (S) -> (T) 和 (T) -> (S)
- 剪枝: 计算最短路 (>ans) 时 break
#pragma comment(linker, "/STACK:36777216")
//#pragma GCC optimize ("O2")
#define LOCAL
//#include "testlib.h"
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <climits>
#include <cassert>
#include <complex>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
#define REP(i, n) for (int i=0;i<n;++i)
#define FOR(i, a, b) for (int i=a;i<b;++i)
#define DWN(i, b, a) for (int i=b-1;i>=a;--i)
#define CPY(A,B) memcpy(A,B,sizeof(A))
#define SZ(A) int((A).size())
#define PB push_back
#define MP(A,B) {A,B}
#define PTT pair<T,T>
#define fi first
#define se second
typedef long long LL;
typedef double DB;
typedef unsigned uint;
typedef unsigned long long uLL;
typedef std::vector<int>VI;
typedef std::vector<char>VC;
typedef std::vector<std::string>VS;
typedef std::vector<LL>VL;
typedef std::vector<DB>VF;
typedef std::pair<int, int> PII;
typedef std::vector<PII> VPII;
template<class T> inline T& RD(T &);
template<class T> inline void OT(const T &);
//inline int RD(){int x; return RD(x);}
inline LL RD() {LL x; return RD(x);}
inline DB& RF(DB &);
inline DB RF() {DB x; return RF(x);}
inline char* RS(char *s);
inline char& RC(char &c);
inline char RC();
inline char& RC(char &c) {scanf(" %c", &c); return c;}
inline char RC() {char c; return RC(c);}
//inline char& RC(char &c){c = getchar(); return c;}
//inline char RC(){return getchar();}
template<class T> inline T& RDD(T &);
inline LL RDD() {LL x; return RDD(x);}
template<class T0, class T1> inline T0& RD(T0 &x0, T1 &x1) {RD(x0), RD(x1); return x0;}
template<class T0, class T1, class T2> inline T0& RD(T0 &x0, T1 &x1, T2 &x2) {RD(x0), RD(x1), RD(x2); return x0;}
template<class T0, class T1, class T2, class T3> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3) {RD(x0), RD(x1), RD(x2), RD(x3); return x0;}
template<class T0, class T1, class T2, class T3, class T4> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4) {RD(x0), RD(x1), RD(x2), RD(x3), RD(x4); return x0;}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5) {RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5); return x0;}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6) {RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6); return x0;}
template<class T0, class T1> inline void OT(const T0 &x0, const T1 &x1) {OT(x0), OT(x1);}
template<class T0, class T1, class T2> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2) {OT(x0), OT(x1), OT(x2);}
template<class T0, class T1, class T2, class T3> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3) {OT(x0), OT(x1), OT(x2), OT(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4) {OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5) {OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5, const T6 &x6) {OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}
inline char& RC(char &a, char &b) {RC(a), RC(b); return a;}
inline char& RC(char &a, char &b, char &c) {RC(a), RC(b), RC(c); return a;}
inline char& RC(char &a, char &b, char &c, char &d) {RC(a), RC(b), RC(c), RC(d); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e) {RC(a), RC(b), RC(c), RC(d), RC(e); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f) {RC(a), RC(b), RC(c), RC(d), RC(e), RC(f); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f, char &g) {RC(a), RC(b), RC(c), RC(d), RC(e), RC(f), RC(g); return a;}
inline DB& RF(DB &a, DB &b) {RF(a), RF(b); return a;}
inline DB& RF(DB &a, DB &b, DB &c) {RF(a), RF(b), RF(c); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d) {RF(a), RF(b), RF(c), RF(d); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e) {RF(a), RF(b), RF(c), RF(d), RF(e); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f) {RF(a), RF(b), RF(c), RF(d), RF(e), RF(f); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f, DB &g) {RF(a), RF(b), RF(c), RF(d), RF(e), RF(f), RF(g); return a;}
inline void RS(char *s1, char *s2) {RS(s1), RS(s2);}
inline void RS(char *s1, char *s2, char *s3) {RS(s1), RS(s2), RS(s3);}
template<class T0, class T1>inline T0& RDD(T0&a, T1&b) {RDD(a), RDD(b); return a;}
template<class T0, class T1, class T2>inline T1& RDD(T0&a, T1&b, T2&c) {RDD(a), RDD(b), RDD(c); return a;}
template<class T> inline void RST(T &A) {memset(A, 0, sizeof(A));}
template<class T> inline void FLC(T &A, int x) {memset(A, x, sizeof(A));}
template<class T> inline void CLR(T &A) {A.clear();}
template<class T0, class T1> inline void RST(T0 &A0, T1 &A1) {RST(A0), RST(A1);}
template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2) {RST(A0), RST(A1), RST(A2);}
template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3) {RST(A0), RST(A1), RST(A2), RST(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4) {RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5) {RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6) {RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x) {FLC(A0, x), FLC(A1, x);}
template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2, int x) {FLC(A0, x), FLC(A1, x), FLC(A2, x);}
template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, int x) {FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x);}
template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, int x) {FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, int x) {FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6, int x) {FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x), FLC(A6, x);}
template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1) {CLR(A0), CLR(A1);}
template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2) {CLR(A0), CLR(A1), CLR(A2);}
template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3) {CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4) {CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5) {CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6) {CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
template<class T> inline void CLR(T &A, int n) {REP(i, n) CLR(A[i]);}
template<class T> inline bool EPT(T &a) {return a.empty();}
template<class T> inline T& SRT(T &A) {sort(ALL(A)); return A;}
template<class T, class C> inline T& SRT(T &A, C B) {sort(ALL(A), B); return A;}
template<class T> inline T& RVS(T &A) {reverse(ALL(A)); return A;}
template<class T> inline T& UNQQ(T &A) {A.resize(unique(ALL(A)) - A.begin()); return A;}
template<class T> inline T& UNQ(T &A) {SRT(A); return UNQQ(A);}
//}
/** I/O Accelerator Interface .. **/
#define g (c=getchar())
#define d isdigit(g)
#define p x=x*10+c-'0'
#define n x=x*10+'0'-c
#define pp l/=10,p
#define nn l/=10,n
template<class T> inline T& RD(T &x) {char c; while(!d); x = c - '0'; while(d)p; return x;}
template<class T> inline T& RDD(T &x) {
char c;
while(g, c != '-' && !isdigit(c));
if(c == '-') {x = '0' - g; while(d)n;}
else {x = c - '0'; while(d)p;}
return x;
}
inline DB& RF(DB &x) {
//scanf("%lf", &x);
char c;
while(g, c != '-' && c != '.' && !isdigit(c));
if(c == '-')if(g == '.') {x = 0; DB l = 1; while(d)nn; x *= l;}
else {x = '0' - c; while(d)n; if(c == '.') {DB l = 1; while(d)nn; x *= l;}}
else if(c == '.') {x = 0; DB l = 1; while(d)pp; x *= l;}
else {x = c - '0'; while(d)p; if(c == '.') {DB l = 1; while(d)pp; x *= l;}}
return x;
}
#undef nn
#undef pp
#undef n
#undef p
#undef d
#undef g
inline char* RS(char *s) {
//gets(s);
scanf("%s", s);
return s;
}
LL last_ans; int Case; template<class T> inline void OT(const T &x) {
printf("Case #%d: ", ++Case);
//printf("%lld
", x);
//printf("%.9f
", x);
printf("%d
", x);
//cout << x << endl;
//last_ans = x;
}
/** I/O Accelerator Interface .. **/
/* ........................................................... */
struct edge {int to, cost, next;};
const int INF = 0x3f3f3f3f;
const int MAX_M = 2e5 + 7;
const int MAX_N = 1e5 + 7;
edge e[MAX_M];
int head[MAX_N], esz;
int ans;
inline void add_edge(int from, int to, int cost) {e[esz].to = to, e[esz].next = head[from]; e[esz].cost = cost; head[from] = esz++;}
std::priority_queue<PII, VPII, std::greater<PII> >Q;
int dis[MAX_N];
int Dijkstra(int s, int t) {
memset(dis,0x3f,sizeof(dis));
dis[s] = 0; Q.push(MP(0, s));
PII p;
while(!Q.empty()) {
p = Q.top(); Q.pop();
if(p.fi > ans) continue;
int v = p.se;
if(dis[v] < p.fi) continue;
for(int i = head[v];~i;i = e[i].next){
edge &ed = e[i];
if(dis[ed.to] > dis[v] + ed.cost) {
dis[ed.to] = ed.cost + dis[v];
Q.push(PII(dis[ed.to], ed.to));
}
}
}
return dis[t];
}
int x[MAX_M], y[MAX_M], v[MAX_M],S[MAX_N];
void solve() {
int n = RD(), m = RD();
int s = n + 1, t = n + 2;
ans = INF;
REP(i, m) RD(x[i], y[i], v[i]);
RD(n); REP(i,n) RD(S[i]);
REP(j, 16) {
esz = 0; memset(head,-1,sizeof(head));
REP(i, n) {
if(S[i] & (1<<j)) add_edge(s, S[i], 0);
else add_edge(S[i], t, 0);
}
if(head[s] == -1) continue;
REP(i, m) add_edge(x[i], y[i], v[i]);
ans = std::min(ans, Dijkstra(s, t));
}
REP(j,16){
esz = 0; memset(head,-1,sizeof(head));
REP(i, n) {
if(S[i] & (1<<j)) add_edge(S[i], t, 0);
else add_edge(s, S[i], 0);
}
if(head[s] == -1) continue;
REP(i, m) add_edge(x[i], y[i], v[i]);
ans = std::min(ans, Dijkstra(s, t));
}
OT(ans);
}
int main() {
int T = RD();
while(T--)solve(); return 0;
}