给定一张 No
,反之输出 Yes
。保证询问中
考虑维护对于走每条边时需要多长时间才能连通最近的两个房子,换句话说,满足这个时间的时候这条边就一定可以被走。具体维护可以考虑建一个超级源点并向所有房子连个边,然后跑个 Dijk 即可,当然直接往队列里把所有房子点都塞进去也行。然后我们可以令
具体地,每次询问将边集里所有新的
同时不难想到即使
存在一道双倍经验 CF1253F Cheap Robot,略有区别,这里简单说一下:这道题的区别就在于询问的是最小的 clear()
之后 shrink_to_fit()
就会 TLE,否则会 MLE,按秩合并会保证合并询问的时候不会复制太多次以保证空间。这个东西的复杂度理论上似乎可以被卡到
xxxxxxxxxx
961
2
3
4
5
6
7
8
9
10
11using namespace std;
12
13mt19937 rnd(random_device{}());
14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
15bool rnddd(int x){return rndd(1, 100) <= x;}
16
17typedef unsigned int uint;
18typedef unsigned long long unll;
19typedef long long ll;
20typedef long double ld;
21
22template < typename T = int >
23inline T read(void);
24
25struct Edge{
26 Edge* nxt;
27 int to;
28 ll val;
29 OPNEW;
30}ed[410000];
31ROPNEW(ed);
32Edge* head[210000];
33
34int N, M, K;
35bitset < 210000 > vis;
36ll dis[210000];
37priority_queue < tuple < ll, int, int >, vector < tuple < ll, int, int > >, greater < tuple < ll, int, int > > > edgs;
38
39class UnionFind{
40private:
41 int fa[210000];
42public:
43 UnionFind(void){for(int i = 1; i <= 201000; ++i)fa[i] = i;}
44 int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}
45 void Union(int origin, int son){fa[Find(son)] = Find(origin);}
46}uf;
47
48void Dijk(void){
49 memset(dis, 0x3f, sizeof dis);
50 priority_queue < pair < ll, int >, vector < pair < ll, int > >, greater < pair < ll, int > > > cur;
51 for(int i = 1; i <= K; ++i)cur.push({dis[i] = 0, i});
52 while(!cur.empty()){
53 int p = cur.top().second; cur.pop();
54 if(vis[p])continue;
55 vis[p] = true;
56 for(auto i = head[p]; i; i = i->nxt)
57 if(dis[p] + i->val < dis[SON])
58 dis[SON] = dis[p] + i->val, cur.push({dis[SON], SON});
59 }
60}
61int main(){
62 N = read(), M = read(), K = read();
63 for(int i = 1; i <= M; ++i){
64 int s = read(), t = read(), v = read();
65 head[s] = new Edge{head[s], t, v};
66 head[t] = new Edge{head[t], s, v};
67 }Dijk();
68 for(int p = 1; p <= N; ++p)
69 for(auto i = head[p]; i; i = i->nxt)
70 edgs.push({i->val + dis[p] + dis[SON], p, SON});
71 int Q = read();
72 while(Q--){
73 int s = read(), t = read(); ll lim = read < ll >();
74 while(!edgs.empty() && get < 0 >(edgs.top()) <= lim)
75 uf.Union(get < 1 >(edgs.top()), get < 2 >(edgs.top())), edgs.pop();
76 printf("%s\n", uf.Find(s) == uf.Find(t) ? "Yes" : "No");
77 }
78 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
79 return 0;
80}
81
82template < typename T >
83inline T read(void){
84 T ret(0);
85 int flag(1);
86 char c = getchar();
87 while(c != '-' && !isdigit(c))c = getchar();
88 if(c == '-')flag = -1, c = getchar();
89 while(isdigit(c)){
90 ret *= 10;
91 ret += int(c - '0');
92 c = getchar();
93 }
94 ret *= flag;
95 return ret;
96}
update-2022_12_20 初稿