Day10 - A - Rescue the Princess ZOJ - 4097
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的更多相关文章
- H - Rescue the Princess ZOJ - 4097 (tarjan缩点+倍增lca)
		
题目链接: H - Rescue the Princess ZOJ - 4097 学习链接: zoj4097 Rescue the Princess无向图缩点有重边+lca - lhc..._博客园 ...
 - sdut 2603:Rescue The Princess(第四届山东省省赛原题,计算几何,向量旋转 + 向量交点)
		
Rescue The Princess Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Several days ago, a b ...
 - 山东省第四届acm.Rescue The Princess(数学推导)
		
Rescue The Princess Time Limit: 1 Sec Memory Limit: 128 MB Submit: 412 Solved: 168 [Submit][Status ...
 - 计算几何 2013年山东省赛 A Rescue The Princess
		
题目传送门 /* 已知一向量为(x , y) 则将它旋转θ后的坐标为(x*cosθ- y * sinθ , y*cosθ + x * sinθ) 应用到本题,x变为(xb - xa), y变为(yb ...
 - sdutoj 2603 Rescue The Princess
		
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2603 Rescue The Princess ...
 - SDUT 2603:Rescue The Princess
		
Rescue The Princess Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Several days ago, a b ...
 - 2013山东省“浪潮杯”省赛 A.Rescue The Princess
		
A.Rescue The PrincessDescription Several days ago, a beast caught a beautiful princess and the princ ...
 - 山东省赛A题:Rescue The Princess
		
http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=3230 Description Several days ago, a beast caught ...
 - 山东省第四届ACM程序设计竞赛A题:Rescue The Princess
		
Description Several days ago, a beast caught a beautiful princess and the princess was put in prison ...
 
随机推荐
- 在Ubuntu_meta 16.04中设置默认Python3.5的命令
			
ubuntu_meta 默认是安装了python2.7 和python3.5两个版本 查看ubuntu的python版本,默认版本是python2.7 输入:python 直接执行这两个命令即可: s ...
 - MQTT Web Toolkit - MQTT 在线客户端及服务器测试
			
MQTT Web Toolkit 是 EMQ 最近开源的一款 MQTT (WebSocket) 测试工具,支持线上 (tools.emqx.io) 访问使用.该工具采用了聊天界面形式,简化了页面操作逻 ...
 - Redis为什么要自己实现一个SDS
			
Redis是使用C语言开发的,在C语言中没有字符串这种数据类型,字符串大都是通过字符数组实现的,但是使用字符数组有以下不足: 1. 字符数组的长度都是固定,容易发生空指针2. 获取字符数组的长度的时候 ...
 - 洛谷 P5057 [CQOI2006]简单题(树状数组)
			
嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...
 - phpsduty安装SSL证书,apache不能启动,解决方案
			
最近给客户开发微信小程序,因为本人也不太懂服务器的安装,(大神勿喷),顾个人一直使用的集成环境,原来一直是客户提供主机什么的,都是我们和客户说一下需要什么环境啊,配置啊,之类的,这次首次自己动手. 废 ...
 - ng-class 动态设置css
			
可使用ng-class 动态设置class ,设置disable后,发现ng-click 居然还可以使用,不知什么原因. <li ng-class="{disabled:!first} ...
 - ios 物流时间轴,自动匹配电话号码,可点击拨打
			
http://www.code4app.com/thread-27587-1-1.html 资讯时间轴(折叠/展开) http://www.code4app.com/thread-32358-1-1. ...
 - 2 Struts2的执行流程&配置文件的加载顺序
			
执行流程: 访问前段页面,通过url访问action 访问xml中Struts2核心过滤器,并执行一组拦截器(这组拦截器在struts-default.xml中,实现了部分功能) 通过action配置 ...
 - Tomcat服务更新流程:
			
Tomcat服务更新流程: 1.把需要更新的war包放在服务器/servers/tomcat9/update下.2.负载均衡服务上把要更新的服务器权重值调为0,即服务不转在这台要更新的服务器上.(重要 ...
 - Python学习第十九课——类的装饰器
			
类的装饰器 # def deco(func): # print('==========') # return func # # # @deco #test=deco(test) # # def tes ...