Problem Description
There is a strange country somewhere which its transportation network was built following some weird rules: Consider the transportation network as a connected undirected graph G with N nodes and M edges(nodes indicate cities,and people can travel from cities to cities by roads connecting them),the condition that every node in G is in at most one simple cycle holds.
One day Q people of the country want to make a travel, i_th people is located at city Ui, wants to move to city Vi(Ui can be equal to Vi),and he especially loves city Pi,so he wonders if there is a path that:

1. starts at Ui;
2. ends at Vi;
3. for every pair of adjacent cities in path,there is a road connecting them.
4. visits every city at most once.
5. visits city Pi;

As a trip advisor,your task is to tell everybody whether there is a path satsifying all his requirements.

 



Input
The input contains several test cases, terminated by EOF. Most of test cases are rather small.
Each testcase contains M + Q + 2 lines. first line contains two integers N, M (1 <= N <= 100000, 1 <= M <= 150000), the number of cities and roads; next M lines each contains two integer b, e indicates that there is a bidirectional-road connecting city b and city e;next line an integer Q (1 ≤ Q ≤ 100000) indicating number of people in that country that want to make a travel, next Q lines each contains three integers Ui, Vi, Pi, denotes the query as we mentioned above.
 



Output
For each test case output Q lines, for i-th query, if there exists such path, output one line "Yes" without quotes, otherwise output one line "No" without quotes.
 



Sample Input
6 7
1 2
1 2
3 4
2 4
5 6
5 6
4 5
5
1 6 3
1 6 4
1 2 5
2 2 2
2 2 3
 



Sample Output
No
Yes
No
Yes
No
 



Source

 //#pragma comment(linker, "/STACK:65536000")
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <algorithm>
#define clr(a,b) memset(a,b,sizeof(a))
#define mpr(a,b) make_pair(a,b)
#define ll long long
#define eps 1e-6
using namespace std; const int N=,M=; /*
* HDU4674
* 一个无向图,每个点最多只属于一个简单环,询问从a到b的简单路径能不能路过c
* 离线处理,先缩点,假设缩点完后a为A,b为B,c为C
* 对每个询问分别求出lca(A,B),lca(A,C),lca(B,C)
* 还要判断两个点求lca的时候,对lca的那个点,进出的联通块分别是哪个点,这个
* 在做完一边lca后再dfs一边就好了
* come记录从父亲节点进入这个联通块的是哪个点
* out数组在dfs中记录当前祖先的状态
* gra数组用来缩点建图,first保存连到下一个联通块的编号,
second保存从该联通块该边连出去的是哪个点
* qu数组用来lca询问
* tlca记录每个lca的值
* pt表示两个点连到lca的时候,进出lca那个联通块的点,-1说明就在lca上
*/
int n,m,q,eid,id,now,top;
int head[N],ed[M],nxt[M];
int dfn[N],low[N],gid[N];
int sta[N],block[N];
vector<pair<int,int> >gra[N],qu[N];
int f[N],vis[N],come[N],out[N],fa[N];
int tlca[*N],pt[*N][];
int aa[N],bb[N],cc[N]; int findfa(int s){return s==fa[s]?s:fa[s]=findfa(fa[s]);} void addedge(int s,int e){
ed[eid]=e;nxt[eid]=head[s];head[s]=eid++;
} void tarjan(int s,int f,int b){
dfn[s]=low[s]=++now;
sta[top++]=s;block[s]=b;
for(int i=head[s];~i;i=nxt[i]){
int e=ed[i];
if(i==f||i==(f^))continue;
if(!dfn[e]){
tarjan(e,i,b);
low[s]=min(low[s],low[e]);
}else
low[s]=min(low[s],dfn[e]);
}
if(low[s]==dfn[s]){
id++;
while(top){
int k=sta[--top];
gid[k]=id;
if(k==s)return ;
}
}
} void lca(int s,int f){
fa[s]=s;
for(int i=;i<(int)gra[s].size();i++){
int e=gra[s][i].first;
if(e==f)continue;
lca(e,s);
fa[findfa(e)]=s;
}
vis[s]=;
for(int i=;i<(int)qu[s].size();i++){
int e=qu[s][i].first,d=qu[s][i].second;
if(vis[e])tlca[d]=findfa(e);
}
} void dfs(int s,int f){
for(int i=;i<(int)qu[s].size();i++){
int d=qu[s][i].second;
int k=(tlca[d]==s)?-:out[tlca[d]];
if(~pt[d][])pt[d][]=k;
else pt[d][]=k;
}
for(int i=;i<(int)gra[s].size();i++){
int e=gra[s][i].first,g=gra[s][i].second;
if(e==f){
come[s]=g;continue;
}
out[s]=g;
dfs(e,s);
}
} int main(){
// freopen("/home/axorb/in","r",stdin);
while(~scanf("%d%d",&n,&m)){
eid=;clr(head,-);
for(int i=;i<m;i++){
int a,b;scanf("%d%d",&a,&b);
addedge(a,b);addedge(b,a);
}
id=now=top=;
for(int i=;i<=n;i++)dfn[i]=;
int cnt=;
for(int i=;i<=n;i++)
if(!dfn[i])tarjan(i,-,++cnt);
for(int i=;i<=id;i++){
gra[i].clear();qu[i].clear();
}
for(int i=;i<=n;i++)
for(int j=head[i];~j;j=nxt[j]){
int s=gid[i],e=gid[ed[j]];
if(s!=e)gra[s].push_back(mpr(e,i));
}
clr(f,);
scanf("%d",&q);
for(int i=;i<q;i++){
int a,b,c;scanf("%d%d%d",&a,&b,&c);
//如果3个点不能到达,则答案肯定否定
if(block[a]!=block[b]){f[i]=;continue;}
if(block[b]!=block[c]){f[i]=;continue;}
if(block[a]!=block[c]){f[i]=;continue;}
//如果起点和终点相同,那个路过的点也必须相同
if(a==b&&a!=c){f[i]=;continue;}
int s=gid[a],e=gid[b],k=gid[c];
qu[s].push_back(mpr(e,i*));
qu[e].push_back(mpr(s,i*));
qu[s].push_back(mpr(k,i*+));
qu[k].push_back(mpr(s,i*+));
qu[e].push_back(mpr(k,i*+));
qu[k].push_back(mpr(e,i*+));
aa[i]=a;bb[i]=b;cc[i]=c;
}
for(int i=;i<=id;i++)vis[i]=;
for(int i=;i<q*;i++)
pt[i][]=pt[i][]=-;
for(int i=;i<=id;i++)
if(!vis[i]){
lca(i,-);
dfs(i,-);
}
for(int i=;i<q;i++){
if(f[i]){
puts("No");continue;
}
if(gid[aa[i]]==gid[bb[i]]){//如果A=B,那个C必须等于A
if(gid[cc[i]]==gid[aa[i]])puts("Yes");
else puts("No");
}
else if(gid[cc[i]]==tlca[i*]){//如果C是lca(A,B)
if(pt[i*][]==-){
//如果AB中有一个等于C,那么当那个点是出口且C不是出口的时候,C就不能到达
int k=(gid[aa[i]]==gid[cc[i]])?aa[i]:bb[i];
if(k==pt[i*][]&&cc[i]!=k) puts("No");
else puts("Yes");
}else{
//如果AB都不是C,那个当AB进出C的是同一个点且不是C,C就不能到达
if(pt[i*][]==pt[i*][]&&cc[i]!=pt[i*][]) puts("No");
else puts("Yes");
}
}else if(tlca[i*+]==gid[cc[i]]&&tlca[i*+]==tlca[i*]){
//如果C是A的祖先,且lca(A,B)=lca(C,B)
//那么当父亲到C的点和C连出去到A的点是同一个点且不是C,那个C就不能到达
int k=(pt[i*+][]==-)?aa[i]:pt[i*+][];
if(come[gid[cc[i]]]==k&&k!=cc[i])puts("No");
else puts("Yes");
}else if(tlca[i*+]==gid[cc[i]]&&tlca[i*+]==tlca[i*]){
//同上
int k=(pt[i*+][]==-)?bb[i]:pt[i*+][];
if(come[gid[cc[i]]]==k&&k!=cc[i])puts("No");
else puts("Yes");
}else puts("No");
}
}
}

 

HDU4674 Trip Advisor的更多相关文章

  1. hdu 4674 Trip Advisor(缩点+倍增lca)

    花了一天半的时间,才把这道题ac= = 确实是道好题,好久没敲这么长的code了,尤其是最后的判定,各种销魂啊~ 题目中给出的条件最值得关注的就是:每个点最多只能在一个环内->原图是由一个个边连 ...

  2. 微软要如何击败Salesforce?Office365、Azure、Dynamics365 全面布局AI | 双语

    微软在上月宣布组建自己的 AI 研究小组.该小组汇集了超过 5000 名计算机科学家和工程师,加上微软内部研究部门,将共同挖掘 AI 技术. 与此同时,亚马逊,Facebook,Google,IBM ...

  3. dynamics 365 AI 解决方案 —— 微软布局

    核心提示:微软在 Office365.Azure 云.Dynamics365 上进行人工智能技术的部署,野心不小. 微软在2016年9月宣布组建自己的 AI 研究小组.该小组汇集了超过 5000 名计 ...

  4. 团队作业(五)——旅游行业的手机App

    首先是作业要求: 在PM 带领下, 每个团队深入分析下面行业的App, 找到行业的Top 5 (从下面的三个备选中,任选一个行业即可) 英语学习/词典App 笔记App 旅游行业的手机App 我们选择 ...

  5. 学习AOP之透过Spring的Ioc理解Advisor

    花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...

  6. SQL Tuning 基础概述08 - SQL Tuning Advisor

    SQL调优顾问 SQL Tuning Advisor的使用案例: 1.构建测试表T 2.定义调整任务 3.修改调整任务参数 4.执行调整任务 5.监控调整任务 6.查看调整任务建议 7.删除调整任务 ...

  7. Spring 通知(Advice)和顾问(Advisor)

    AOP ( Aspect  Oriented Programming  面向切面编程)  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译 ...

  8. 【转】使用SQL Tuning Advisor STA优化SQL

    SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单.智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果.下面介绍一 ...

  9. 如何用 SQL Tuning Advisor (STA) 优化SQL语句

    在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning ...

随机推荐

  1. 创建型设计模式之工厂模式(Abstract Factory)

    结构            意图         提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性     一个系统要独立于它的产品的创建.组合和表示时. 一个系统要由多个 ...

  2. R语言绘制相对性关系图

    准备 第一步就是安装R语言环境以及RStudio 图绘制准备 首先安装库文件,敲入指令,回车 install.packages('corrplot') 然后安装excel导入的插件,点击右上角impo ...

  3. authencated认证登录

    #coding:utf-8 import tornado.httpserver import tornado.ioloop import tornado.options import tornado. ...

  4. Linux下Redis使用

    1. 简介 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. 2. 安装 安装方法如下: # yum i ...

  5. 软中断网卡处理&Linux高性能外部设备处理机制&SMP

    转载:http://blog.csdn.net/freas_1990/article/details/9238183 看了一些linux网卡驱动的处理技术,对有些概念还是无法理解,突然搜到这篇文章,挺 ...

  6. windows下修改Mysql5.7.11初始密码的图文教程

    参考:http://www.jb51.net/article/98481.htm [摘要:1.my-default.ini 更名my.ini 正在解压的目次上面复造my-default.ini一份更名 ...

  7. 本地yum仓库的搭建

    . 1.直接断开网络,模拟生产内网环境 2.将原先的网络yum仓库全部移动到 backup目录下 3.创建本地yum仓库  local_yum.repo vi /etc/yum.repos.d/loc ...

  8. vagrant virtualbox VM inaccessible解决办法

    vagrant无法访问的提示:Please open VirtualBox and clear out your inaccessible virtual machines or find a way ...

  9. C# Socket的粘包处理(转)

    http://www.cnblogs.com/aarond/p/Socket111.html 当socket接收到数据后,会根据buffer的大小一点一点的接收数据,比如: 对方发来了1M的数据量过来 ...

  10. 网易 监控 openstack

    http://www.360doc.com/content/16/0416/08/13792507_551022987.shtml