Princess Cjb is caught by Heltion again! Her knights Little Sub and Little Potato are going to Heltion Kingdom to rescue her.

Heltion Kingdom is composed of nn islands, numbered from 11 to nn. There are mm bridges in the kingdom, among which the ii-th bridge connects the l_ili​-th island and the r_iri​-th island. The knights can go through each bridge in both directions.

Landing separately on the vv-th and the ww-th island, the two knights start their journey heading to the uu-th island where the princess is imprisoned. However, as the knights are fat and the bridges are unstable, there will be a risk of breaking down the bridge and falling into the water if they go through one or more common bridges during their journey.

Thus, to successfully bring back the princess, two paths \textbf{with no common bridges} are needed: one starts from the vv-th island and leads to the uu-th island, while the other starts from the ww-th island and also leads to the uu-th island.

As the princess is caught very often, the knights will ask you for help qq times. Each time, given their starting islands and their goal, you need to tell them whether it's possible to find two paths satisfying the constraints above.

Input

There are multiple test cases. The first line of the input contains an integer TT, indicating the number of test cases. For each test case:

The first line contains three integers nn, mm and qq (1 \le n \le 10^51≤n≤105, 0 \le m \le 2 \times 10^50≤m≤2×105, 1 \le q \le 10^51≤q≤105), indicating the number of islands, the number of bridges and the number of queries.

The following mm lines describe the bridges. The ii-th line contains two integers l_ili​ and r_iri​ (1 \le l_i,r_i \le n1≤li​,ri​≤n), indicating the two islands the ii-th bridge connects. Notice that different bridges may connect the same pair of islands and a bridge may connect an island to itself.

The following qq lines describe the queries. The ii-th line contains three integers u_iui​, v_ivi​ and w_iwi​ (1 \le u_i,v_i,w_i \le n1≤ui​,vi​,wi​≤n), indicating the island where the princess is imprisoned and the starting islands of the two knights.

It's guaranteed that the sum of nn of all test cases will not exceed 5 \times 10^55×105, the sum of mm of all test cases will not exceed 10^6106, and the sum of qq of all test cases will not exceed 5 \times 10^55×105.

Output

For each test case output qq lines indicating the answers of the queries. For each query, if two paths meeting the constraints can be found, output "Yes" (without quotes), otherwise output "No" (without quotes).

Sample Input

2
6 7 4
1 2
2 3
3 1
4 5
5 6
6 4
1 4
4 1 3
1 4 2
1 2 3
1 3 3
2 1 2
1 2
1 1 1
2 1 2

Sample Output

No
Yes
Yes
Yes
Yes
Yes

Hint

For the first sample test case:

  • For the 2nd query, we can select the paths 4-1 and 2-1.
  • For the 3rd query, we can select the paths 2-1 and 3-1.
  • For the 4th query, we can select the paths 3-1 and 3-2-1.

For the second sample test case:

  • For the 1st query, as the knights and the princess are on the same island initially, the answer is "Yes".
  • For the 2nd query, as one of the knights are on the same island with the princess initially, he does not need to cross any bridge. The other knight can go from island 1 to island 2 directly.

思路:求两个点不同边路径,想到边双缩点,这题需要考虑重边和多个连通块,对每个连通块缩点,跑lca,判断lca即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<map>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<LL, LL> PLL; const int maxm = 2e5+; int dfn[maxm], low[maxm], s[maxm], dfscnt, top, bcc, bccnum[maxm], block[maxm], father[maxm], blocknum, depth[maxm], grand[maxm][];
int vis[maxm], N;
struct Node {
int u, v;
}; vector<int> G[maxm], G2[maxm];
vector<Node> edges; void addedge(int u, int v) {
edges.push_back(Node{u, v});
G2[u].push_back(edges.size()-);
edges.push_back(Node{v, u});
G2[v].push_back(edges.size()-);
} void init(int n) {
for(int i = ; i <= n; ++i) G[i].clear(), G2[i].clear();
edges.clear();
dfscnt = top = ;
bcc = blocknum = ;
memset(vis, , sizeof(vis));
memset(block, , sizeof(block)), memset(father, , sizeof(father));
memset(dfn, , sizeof(dfn)), memset(low, , sizeof(low));
memset(bccnum, , sizeof(bccnum));
} void tarjan(int u, int fa) { //边双缩点
int v, k = , siz = G[u].size();
dfn[u] = low[u] = ++dfscnt;
s[++top] = u;
father[u] = fa;
for(int i = ; i < siz; ++i) {
v = G[u][i];
if(v == fa && !k) { // 判重边
k++;
continue;
}
if(!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
} else
low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]) {
do {
v = s[top--];
bccnum[v] = bcc;
} while(u != v);
bcc++;
}
} void dfs1(int u) {
block[u] = blocknum;
int siz = G[u].size();
for(int i = ; i < siz; ++i) {
int v = G[u][i];
if(!block[v])
dfs1(v);
}
} void dfs2(int u, int fa) { // build lca tree
vis[u] = ;
depth[u] = depth[fa] + ;
grand[u][] = fa;
for(int i = ; i <= N; ++i)
grand[u][i] = grand[grand[u][i-]][i-];
int siz = G2[u].size();
for(int i = ; i < siz; ++i) {
int v = edges[G2[u][i]].v;
if(v != fa) {
dfs2(v, u);
}
}
} int lca(int a, int b) {
if(a == b) return a;
if(depth[a] > depth[b]) swap(a, b);
for(int i = N; i >= ; --i)
if(depth[a] <= depth[b] - (<<i)) b = grand[b][i];
if(a == b) return a;
for(int i = N; i >= ; --i) {
if(grand[a][i] == grand[b][i]) continue;
else {
a = grand[a][i], b = grand[b][i];
}
}
return grand[a][];
} void run_case() {
int n, m, q, u, v, w;
cin >> n >> m >> q;
init(n);
for(int i = ; i < m; ++i) {
cin >> u >> v;
G[u].push_back(v), G[v].push_back(u);
}
for(int i = ; i <= n; ++i) //找连通块
if(!block[i]) {
dfs1(i);
blocknum++;
}
for(int i = ; i <= n; ++i) // 缩点
if(!dfn[i])
tarjan(i, i);
N = floor(log(bcc + 0.0) / log(2.0)) + ; //最多能跳的2^i祖先
for(int i = ; i <= n; ++i) {
int v = father[i];
if(bccnum[i] != bccnum[v])
addedge(bccnum[i], bccnum[v]);
}
// build lca tree
for(int i = ; i < bcc; ++i) {
if(!vis[i]) {
dfs2(i, );
}
}
while(q--) {
cin >> u >> v >> w;
// 不同连通块
if(block[u] != block[v] || block[u] != block[w]) {
cout << "No" << "\n";
continue;
}
u = bccnum[u], v = bccnum[v], w = bccnum[w];
// 在同一连通块 不同点
if(u == v || u == w) {
cout << "Yes" << "\n";
continue;
}
if(v == w) {
cout << "No" << "\n";
continue;
}
int uv, uw, vw, uvw;
// u是vw的根即可
uv = lca(u, v), uw = lca(u, w), vw = lca(v, w), uvw = lca(uw, v);
if(vw == uvw && (uv == u || uw == u))
cout << "Yes" << "\n";
else
cout << "No" << "\n";
} } int main() {
ios::sync_with_stdio(false), cin.tie();
int t;
cin >> t;
while(t--)
run_case();
return ;
}

(自用板)

Day10 - A - Rescue the Princess ZOJ - 4097的更多相关文章

  1. H - Rescue the Princess ZOJ - 4097 (tarjan缩点+倍增lca)

    题目链接: H - Rescue the Princess  ZOJ - 4097 学习链接: zoj4097 Rescue the Princess无向图缩点有重边+lca - lhc..._博客园 ...

  2. sdut 2603:Rescue The Princess(第四届山东省省赛原题,计算几何,向量旋转 + 向量交点)

    Rescue The Princess Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Several days ago, a b ...

  3. 山东省第四届acm.Rescue The Princess(数学推导)

    Rescue The Princess Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 412  Solved: 168 [Submit][Status ...

  4. 计算几何 2013年山东省赛 A Rescue The Princess

    题目传送门 /* 已知一向量为(x , y) 则将它旋转θ后的坐标为(x*cosθ- y * sinθ , y*cosθ + x * sinθ) 应用到本题,x变为(xb - xa), y变为(yb ...

  5. sdutoj 2603 Rescue The Princess

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2603 Rescue The Princess ...

  6. SDUT 2603:Rescue The Princess

    Rescue The Princess Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Several days ago, a b ...

  7. 2013山东省“浪潮杯”省赛 A.Rescue The Princess

    A.Rescue The PrincessDescription Several days ago, a beast caught a beautiful princess and the princ ...

  8. 山东省赛A题:Rescue The Princess

    http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=3230 Description Several days ago, a beast caught ...

  9. 山东省第四届ACM程序设计竞赛A题:Rescue The Princess

    Description Several days ago, a beast caught a beautiful princess and the princess was put in prison ...

随机推荐

  1. windows 配置hadoop环境

    在idea运行spark程序的时候报错:java.io.IOException: Could not locate executable null\bin\winutils.exe in the Ha ...

  2. 创建Ajax兼容

    var request = new XMLHttpRequest(); IE7以下: var request = new ActiveXObject("Microsoft.XMLHTTP&q ...

  3. 转专业后补修C语言的一些体会(3)

    1.指针:指针是C语言最为强大的工具之一,有着很多优点,比如可以改善子程序的效率,为动态数据结构提供支持,为C的动态内存分配系统提供支持,为函数提供修改变量值的手段.但指针的使用十分困难.会出现很多意 ...

  4. linux下postgres创建hive数据库

    操作步骤 #登录 [root@xxx01 ~]# su postgres bash-4.2$ psql -U postgres could not change directory to " ...

  5. Update(Stage4):Spark Streaming原理_运行过程_高级特性

    Spark Streaming 导读 介绍 入门 原理 操作 Table of Contents 1. Spark Streaming 介绍 2. Spark Streaming 入门 2. 原理 3 ...

  6. cmake 环境安装与使用

    CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...

  7. maven搭建ssm 完整过程

    https://blog.csdn.net/qq_28008917/article/details/79755935

  8. 对list集合的内容分组

    /** * 把list集合里的内容按照len大小分组 * @param list * @param len * @return */ private static List<List<St ...

  9. 无法获得锁/var/lib/dpkg/lock - open(11.资源暂时不可用)

    E:无法获得锁/var/lib/dpkg/lock  - open(11.资源暂时不可用) E:无法锁定资源目录(/var/lib/dpkg)是否有其他进程正占用它? 解决方案: sudo rm /v ...

  10. ios 物流时间轴,自动匹配电话号码,可点击拨打

    http://www.code4app.com/thread-27587-1-1.html 资讯时间轴(折叠/展开) http://www.code4app.com/thread-32358-1-1. ...