1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> #include <vector> #define MAXN (200000 + 5) #define MAXM (500000 + 5) #define MAXL (40 + 5) using namespace std; struct edg { int from, to, next, cost; } tb[MAXN << 1], eb[MAXM << 1], kb[MAXM]; struct node { int from, bh, cost; node() {} node(int fr, int b, int co): from(fr), bh(b), cost(co) {} }; struct cmp1 { bool operator () (const node& x, const node& y) { return x.cost > y.cost; } }; int tg[MAXN], cntt, eg[MAXN], cnte, cntk, n, m, s, c[MAXN], q, lgn, d[MAXN][MAXL], deep[MAXN], maxc[MAXN][MAXL], fa[MAXN], dis[MAXN], belong[MAXN]; void adn(edg* bx, int* gx, int& cntx, int from, int to, int cost) { bx[++cntx].next = gx[from]; bx[cntx].from = from, bx[cntx].to = to, bx[cntx].cost = cost; gx[from] = cntx; } int find(int x) { return (fa[x] == x) ? x : (fa[x] = find(fa[x])); } void uni(int x, int y) { fa[find(x)] = find(y); } bool cmp(const edg x, const edg y) { return x.cost < y.cost; } void init() { bool vis[MAXN]; memset(vis, false, sizeof(vis)); memset(dis, 0x7f, sizeof(dis)); priority_queue<node, vector<node>, cmp1> q; for (int i = 1; i <= s; i++) q.push(node(c[i], c[i], dis[c[i]] = 0)); while (!q.empty()) { node dq = q.top(); q.pop(); if (vis[dq.bh]) continue; vis[dq.bh] = true; belong[dq.bh] = dq.from; for (int i = eg[dq.bh]; i; i = eb[i].next) if (dis[eb[i].to] > dis[dq.bh] + eb[i].cost) q.push(node(dq.from, eb[i].to, dis[eb[i].to] = dis[dq.bh] + eb[i].cost)); } } void kruskal() { sort(kb + 1, kb + m + 1, cmp); for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 1; i <= m; i++) if (find(kb[i].from) != find(kb[i].to)) { uni(kb[i].from, kb[i].to); adn(tb, tg, cntt, kb[i].from, kb[i].to, kb[i].cost); adn(tb, tg, cntt, kb[i].to, kb[i].from, kb[i].cost);
} } void dfs(int dq) { deep[dq] = deep[d[dq][0]] + 1; for (int i = 1; i <= lgn; i++) d[dq][i] = d[d[dq][i - 1]][i - 1], maxc[dq][i] = max(maxc[d[dq][i - 1]][i - 1], maxc[dq][i - 1]); for (int i = tg[dq]; i; i = tb[i].next) if (tb[i].to != d[dq][0]) d[tb[i].to][0] = dq, maxc[tb[i].to][0] = tb[i].cost, dfs(tb[i].to); } int lca(int x, int y) { int re = 0; if (deep[x] < deep[y]) swap(x, y); for (int i = lgn; i >= 0; i--) if (deep[d[x][i]] >= deep[y]) re = max(maxc[x][i], re), x = d[x][i]; if (x == y) return re; for (int i = lgn; i >= 0; i--) if (d[x][i] != d[y][i]) re = max(re, max(maxc[x][i], maxc[y][i])), x = d[x][i], y = d[y][i]; return max(re, max(maxc[x][0], maxc[y][0])); } int lg(int x) { int re = 0; while ((1 << re) < x) ++re; return re; } int main() { scanf("%d%d%d", &n, &s, &m); lgn = lg(n); for (int i = 1; i <= s; i++) scanf("%d", &c[i]); for (int i = 1, srx, sry, src; i <= m; i++) scanf("%d%d%d", &srx, &sry, &src), adn(eb, eg, cnte, srx, sry, src), adn(eb, eg, cnte, sry, srx, src); init();
for (int i = 1; i <= cnte; i += 2) { ++cntk; kb[cntk].from = belong[eb[i].from]; kb[cntk].to = belong[eb[i].to]; kb[cntk].cost = dis[eb[i].from] + dis[eb[i].to] + eb[i].cost; } kruskal(); for (int i = 1; i <= s; i++) if (!d[c[i]][0]) maxc[c[i]][0] = 0, d[c[i]][0] = 1, dfs(c[i]); int q; scanf("%d", &q); for (int i = 1, srx, sry, srb; i <= q; i++) { scanf("%d%d%d", &srx, &sry, &srb); if (find(belong[srx]) != find(belong[sry]) || lca(belong[srx], belong[sry]) > srb) puts("NIE"); else puts("TAK"); } return 0; }
|