The 19th Zhejiang University Programming Contest - H
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 islands, numbered from to . There are bridges in the kingdom, among which the -th bridge connects the -th island and the -th island. The knights can go through each bridge in both directions.
Landing separately on the -th and the -th island, the two knights start their journey heading to the -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 -th island and leads to the -th island, while the other starts from the -th island and also leads to the -th island.
As the princess is caught very often, the knights will ask you for help 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.
题意
意识到首先可以进行缩点,图中所有的桥将整个图分成了数个联通快,联通块内的点之间一定有至少两条路可以相互到达。
用Tarjan求出所有的桥,缩点之后意识到整个图变成了一片森林(如果保证图联通就是一颗树),可以发现如果存在合理的路,终点所在的点一定在两个骑士的起点中间,类似
的情况,三角形是终点,当然三个点之间可以插入任意个点。
那问题就变成了判断一棵树上一个点是否在两个点中间的情况,意识到情况只有
和
两种情况(u,v为起点,标三角形的为终点),利用lca的方式判断是否满足这两种情况即可,不满足即为NO
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = ,f = ;char c = getchar();while (c<'' || c>''){if (c == '-') f = -;c = getchar();}
while (c >= ''&&c <= ''){x = x * + c - '';c = getchar();}return x*f;}
const double eps = 1e-;
const int maxn = 2e5 + ;
const int maxm = 4e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
struct Edge{
int to,next;
bool cut;
}edge[maxm * ];
int head[maxn],tot;
const int SP = ;
int pa[maxn][SP],dep[maxn];
int scc[maxn];
vector<int>P[maxn];
int ind[maxn];
int low[maxn],dfn[maxn],Stack[maxn],Index,top;
bool Instack[maxn];
int fa[maxn],fa2[maxn];
void add(int u,int v){
edge[tot].to = v;
edge[tot].next = head[u];
edge[tot].cut = ;
head[u] = tot++;
}
void Tarjan(int u,int pre){
int v;
low[u] = dfn[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
int son = ;
int pre_cnt = ;
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == pre && pre_cnt == ){
pre_cnt++;
continue;
}
if(!dfn[v]){
son++;
Tarjan(v,u);
if(low[u] > low[v]) low[u] = low[v];
if(low[v] > dfn[u]){
edge[i].cut = edge[i ^ ].cut = true;
}
}else if(low[u] > dfn[v]){
low[u] = dfn[v];
}
}
Instack[u] = false;
top--;
}
int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
int find2(int x){
if(x == fa2[x]) return x;
return fa2[x] = find2(fa2[x]);
}
void Union2(int a,int b){
a = find2(a); b = find2(b);
fa2[a] = b;
}
void Union(int a,int b){
a = find(a) ; b = find(b);
fa[a] = b;
}
bool vis[maxn];
void dfs(int u,int la){
pa[u][] = la; dep[u] = dep[la] + ;
for(int i = ; i < SP; i ++) pa[u][i] = pa[pa[u][i - ]][i - ];
for(int i = ; i < P[u].size(); i ++){
int v = P[u][i];
if(v == la) continue;
dfs(v,u);
}
}
int lca(int u,int v){
if(dep[u] < dep[v]) swap(u,v);
int t = dep[u] - dep[v];
for(int i = ; i < SP; i ++) if(t & ( << i)) u = pa[u][i];
for(int i = SP - ; i >= ; i --){
int uu = pa[u][i],vv = pa[v][i];
if(uu != vv){
u = uu; v = vv;
}
}
return u == v?u:pa[u][];
}
vector<PII>E;
int main(){
int T; Sca(T);
while(T--){
N = read(),M = read(),K = read();
E.clear();
for(int i = ; i <= N ; i ++){
vis[i] = low[i] = dfn[i] = Instack[i] = ;
head[i] = -;
fa2[i] = fa[i] = i;
}
Index = top = tot = ;
for(int i = ; i <= M ; i ++){
int u = read(),v = read();
add(u,v); add(v,u);
} for(int i = ; i <= N ; i ++) if(!dfn[i]) Tarjan(i,i);
for(int i = ; i <= N ; i ++){
for(int j = head[i]; ~j ; j = edge[j].next){
int v = edge[j].to;
if(!edge[j].cut) Union(i,v);
else E.pb(mp(i,v));
Union2(i,v);
}
}
int cnt = ;
for(int i = ; i <= N ; i ++){
if(fa[i] == i) scc[++cnt] = i;
}
for(int i = ; i < E.size(); i ++){
if(E[i].fi <= E[i].se) continue;
int a = find(E[i].fi),b = find(E[i].se);
if(a == b) continue;
P[a].pb(b); P[b].pb(a);
}
for(int i = ; i <= N ; i ++){
int x = find2(scc[i]);
if(!vis[x]){
vis[x] = ;
dep[scc[i]] = ;
dfs(scc[i],);
}
}
for(int i = ; i <= K; i ++){
int w = read(),u = read(),v = read();
int pw = find2(w),pu = find2(u),pv = find2(v);
if(pw != pu || pw != pv){
puts("No"); continue;
}
int fw = find(w),fu = find(u),fv = find(v);
if(dep[fu] > dep[fv]) swap(fu,fv);
if(fw == fv || fu == fw){
puts("Yes");
continue;
}
int l = lca(fu,fv);
if(lca(fv,fw) == fw && lca(fw,fu) == fu){
puts("Yes");
continue;
}
if(lca(fw,l) == l && (lca(fv,fw) == fw || lca(fu,fw) == fw)){
puts("Yes");
continue;
}
puts("No");
}
for(int i = ; i <= cnt ; i ++) P[scc[i]].clear();
}
return ;
}
The 19th Zhejiang University Programming Contest - H的更多相关文章
- The 19th Zhejiang University Programming Contest Sponsored by TuSimple (Mirror)
http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=391 A Thanks, TuSimple! Time ...
- 2019 The 19th Zhejiang University Programming Contest
感想: 今天三个人的状态比昨天计院校赛的状态要好很多,然而三个人都慢热体质导致签到题wa了很多发.最后虽然跟大家题数一样(6题),然而输在罚时. 只能说,水题还是刷得少,看到签到都没灵感实在不应该. ...
- The 19th Zhejiang University Programming Contest Sponsored by TuSimple (Mirror) B"Even Number Theory"(找规律???)
传送门 题意: 给出了三个新定义: E-prime : ∀ num ∈ E,不存在两个偶数a,b,使得 num=a*b;(简言之,num的一对因子不能全为偶数) E-prime factorizati ...
- zoj 4020 The 18th Zhejiang University Programming Contest Sponsored by TuSimple - G Traffic Light(广搜)
题目链接:The 18th Zhejiang University Programming Contest Sponsored by TuSimple - G Traffic Light 题解: 题意 ...
- The 16th Zhejiang University Programming Contest-
Handshakes Time Limit: 2 Seconds Memory Limit: 65536 KB Last week, n students participated in t ...
- The 18th Zhejiang University Programming Contest Sponsored by TuSimple -C Mergeable Stack
题目链接 题意: 题意简单,就是一个简单的数据结构,对栈的模拟操作,可用链表实现,也可以用C++的模板类来实现,但是要注意不能用cin cout,卡时间!!! 代码: #include <std ...
- The 18th Zhejiang University Programming Contest Sponsored by TuSimple
Pretty Matrix Time Limit: 1 Second Memory Limit: 65536 KB DreamGrid's birthday is coming. As hi ...
- ZOJ 4016 Mergeable Stack(from The 18th Zhejiang University Programming Contest Sponsored by TuSimple)
模拟题,用链表来进行模拟 # include <stdio.h> # include <stdlib.h> typedef struct node { int num; str ...
- The 17th Zhejiang University Programming Contest Sponsored by TuSimple A
Marjar Cola Time Limit: 1 Second Memory Limit: 65536 KB Marjar Cola is on sale now! In order to ...
随机推荐
- 清理mac的硬盘空间,清理Xcode,清除“其他”
下面是一些清理的方法:打开Finder使用快捷键command+shift+g输入路径即可进入该文件夹 1. 移除DerivedData,建议定期清理,会重新生成 此文件夹内是模拟器运行每个APP生成 ...
- vivo7.0以上系统如何无需Root激活Xposed框架的方法
在较多公司的引流或者业务操作中,基本都需要使用安卓的黑高科技术Xposed框架,几天前我们公司购买了一批新的vivo7.0以上系统,基本都都是基于7.0以上版本,基本都不能够获取Root的su超级权限 ...
- 基于Android的模拟点击探索
前言 压力测试中,一般会用到自动化测试.准备写一个APP,可以记录屏幕上的点击事件,然后通过shell命令来模拟自动执行.shell指令,比较容易实现.那么,关键的一步是获取点击的坐标.对于Andro ...
- 工具资源系列之给虚拟机装个centos
前文我们已经讲解了如何在 mac 系统上安装虚拟机软件,这节我们接着讲解如何利用虚拟机安装 centos 镜像. 安装镜像的大致步骤基本相同,只不过是配置项略显不同而已,如果需要安装其他系统镜像,请参 ...
- selenium-测试框架搭建(十三)
思路 分离业务代码和测试数据,提高代码可维护性,实现自动化,减少重复劳动. 一个测试框架大概由配置文件,测试数据,测试用例,相关文件(发送邮件等),测试日志,断言和测试报告等模块组成. 结构 以页面为 ...
- 【SpringBoot笔记】SpringBoot如何正确关闭应用
关闭Spring Boot应用程序,我们可以通过OS命令kill -9 进程ID 实现将进程杀死.但是,有没有一种更好的方式,比如通过REST请求实现?Spring Boot Actoator提供了实 ...
- c/c++ 模板函数的重载
模板函数的重载 普通函数可以重载,模板函数也可以重载,但规则复杂 有下面2个函数,名字相同,返回值相同就,参数不同,符合重载. template<typename T> std::stri ...
- 教你在浏览器里做出EXCEL的效果
在浏览器里做出EXCEL的效果,复制.粘贴.设置公式.双击编辑等效果,如果自己开发的话,比较麻烦,建议使用成熟的插件.这里介绍使用智表ZCELL插件,实现用户快捷操作. 首先下载插件,引入到页面中,一 ...
- Java 7 和 Java 8 中的 HashMap原理解析
HashMap 可能是面试的时候必问的题目了,面试官为什么都偏爱拿这个问应聘者?因为 HashMap 它的设计结构和原理比较有意思,它既可以考初学者对 Java 集合的了解又可以深度的发现应聘者的数据 ...
- kvm虚拟化介绍
一.虚拟化分类 1.虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机.在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互相 ...