题意

https://www.luogu.org/problemnew/show/P5292


思考

最朴素的想法,从可行的二元组(u,v)向外拓展,及u的出边所指的颜色与v的出边所指的颜色若相同,继续更新二元组(u',v'),复杂度约为O(m2)。

我们发现,很多时候边上的转移其实是没有必要的,因为有很多情况能转移到相同的字符串,因此我们要删去一些边,并且使得不改变原图的性质。

先考虑原图中边的两端颜色相同的边构成的连通块,若为二分图,则取其任意生成树;若不为二分图,则取其任意生成树,并添加一个自环。

二分图的意思,就是相同颜色段的长度只与奇偶性有关,当字符串另一端不断添加相同字符的同时,二分图中的字符可以不断地在A集合与B集合中转换。

两端颜色不同的边构成的连通块,也是取其任意生成树。

这样边数为O(n)级别,复杂度为O(n2)。


代码

 // luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int maxn=5E5+;
int head[maxn*],size,n,m,x,y,color[maxn],flag,q;
char c[maxn];
bool f[][],can[maxn];
struct edge{int from,to,next;};
struct pt{int x,y;};
queue<pt>Q;
struct graph
{
edge E[maxn*];
int head[maxn*],size;
void add(int u,int v)
{
E[++size].to=v;
E[size].next=head[u];
E[size].from=u;
head[u]=size;
}
}A,B,G;
void dfs1(int u,int now)
{
color[u]=now;
for(int i=A.head[u];i;i=A.E[i].next)
{
int v=A.E[i].to;
if(now==color[v])flag=;
if(color[v])continue;
G.add(u,v);
G.add(v,u);
if(now==)dfs1(v,);
else dfs1(v,);
}
}
void dfs2(int u)
{
color[u]=;
for(int i=B.head[u];i;i=B.E[i].next)
{
int v=B.E[i].to;
if(color[v])continue;
G.add(u,v);
G.add(v,u);
dfs2(v);
}
}
void init1()
{
for(int i=;i<=A.size;++i)
can[A.E[i].from]=can[A.E[i].to]=;
for(int u=;u<=n;++u)
{
if(color[u]||!can[u])continue;
flag=;
dfs1(u,);
if(flag)G.add(u,u);
}
}
void init2()
{
memset(color,,sizeof(color));
memset(can,,sizeof(can));
for(int i=;i<=B.size;++i)
can[B.E[i].from]=can[B.E[i].to]=;
for(int u=;u<=n;++u)
{
if(color[u]||!can[u])continue;
dfs2(u);
}
}
void work()
{
while(!Q.empty())
{
pt u=Q.front();
Q.pop();
for(int i=G.head[u.x];i;i=G.E[i].next)
{
for(int j=G.head[u.y];j;j=G.E[j].next)
{
int u=G.E[i].to,v=G.E[j].to;
if(c[u]==c[v])
{
if(!f[u][v])Q.push((pt){u,v});
f[u][v]=f[v][u]=;
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m>>q;
for(int i=;i<=n;++i)
{
cin>>c[i];
f[i][i]=;
Q.push((pt){i,i});
}
for(int i=;i<=m;++i)
{
cin>>x>>y;
if(c[x]==c[y])
{
A.add(x,y),A.add(y,x);
f[x][y]=f[y][x]=;
Q.push((pt){x,y});
}
else B.add(x,y),B.add(y,x);
}
init1();
init2();
work();
for(int i=;i<=q;++i)
{
cin>>x>>y;
if(f[x][y])cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return ;
}

[HNOI2019]校园旅行的更多相关文章

  1. 【BZOJ5492】[HNOI2019]校园旅行(bfs)

    [HNOI2019]校园旅行(bfs) 题面 洛谷 题解 首先考虑暴力做法怎么做. 把所有可行的二元组全部丢进队列里,每次两个点分别向两侧拓展一个同色点,然后更新可行的情况. 这样子的复杂度是\(O( ...

  2. [HNOI2019]校园旅行(构造+生成树+动规)

    题目 [HNOI2019]校园旅行 做法 最朴素的做法就是点对扩展\(O(m^2)\) 发现\(n\)比较小,我们是否能从\(n\)下手减少边数呢?是肯定的 单独看一个颜色的联通块,如果是二分图,我们 ...

  3. Luogu P5292 [HNOI2019]校园旅行

    非常妙的一道思博题啊,不愧是myy出的题 首先我们考虑一个暴力DP,直接开一个数组\(f_{i,j}\)表示\(i\to j\)的路径能否构成回文串 考虑直接拿一个队列来转移,队列里存的都是\(f_{ ...

  4. 洛谷P5292 [HNOI2019]校园旅行(二分图+最短路)

    题面 传送门 题解 如果暴力的话,我们可以把所有的二元组全都扔进一个队列里,然后每次往两边更新同色点,这样的话复杂度是\(O(m^2)\) 怎么优化呢? 对于一个同色联通块,如果它是一个二分图,我们只 ...

  5. [LOJ3057] [HNOI2019] 校园旅行

    题目链接 LOJ:https://loj.ac/problem/3057 洛谷:https://www.luogu.org/problemnew/show/P5292 Solution 先膜一发\(m ...

  6. 【洛谷5292】[HNOI2019] 校园旅行(思维DP)

    点此看题面 大致题意: 给你一张无向图,每个点权值为\(0\)或\(1\),多组询问两点之间是否存在一条回文路径. 暴力\(DP\) 首先,看到\(n\)如此之小(\(n\le5000\)),便容易想 ...

  7. bzoj5492:[Hnoi2019]校园旅行

    传送门 %%%myy 考虑30分做法:暴力bfs,\(f[i][j]\)表示\(i\)到\(j\)可以形成回文串 然而为什么我场上只想到了70分做法,完全没想到30分怎么写.. 100分: 考虑缩边, ...

  8. [HNOI2019]校园旅行(建图优化+bfs)

    30分的O(m^2)做法应该比较容易想到:令f[i][j]表示i->j是否有解,然后把每个路径点数不超过2的有解状态(u,v)加入队列,然后弹出队列时,两点分别向两边搜索边,发现颜色一样时,再修 ...

  9. Loj #3057. 「HNOI2019」校园旅行

    Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...

随机推荐

  1. ASCII对应码表-键值(完整版)

    ASCII对应码表-键值(完整版) Bin (二进制) Oct (八进制) Dec (十进制) Hex (十六进制) 缩写/字符 解释 0000 0000 00 0 0x00 NUL(null) 空字 ...

  2. 面向复杂应用,Node.js中的IoC容器 -- Rockerjs/core

    Rockerjs Core 项目地址 项目主页 基于 TypeScript 和注解的轻量级IoC容器,提供了依赖注入.面向切面编程及异常处理等功能.Rockerjs Core可在任意工程中引入,是一个 ...

  3. HDU 4348 To the moon(主席树 区间更新)题解

    题意: 给一个数组A[1] ~ A[n],有4种操作: Q l r询问l r区间和 C l r v给l r区间每个数加v H l r t询问第t步操作的时候l r区间和 B t返回到第t步操作 思路: ...

  4. 优雅的使用windows

    1. 快捷键 win+数字键:打开任务栏对应位置的程序 eg:快捷打开程序,重复该组合键有两个效果,如果只打开了一个窗口,再次按下组合键即可最小化,如果打开了多个窗口,则可以在同一程序的多个窗口中切换 ...

  5. List集合流处理类型小结

    本文为博主原创,未经允许不得转载 对应实体类 import lombok.Getter; import lombok.Setter; @Getter @Setter public class Stud ...

  6. Mybatis学习之一

    mybatis是目前市面上最流行的ORM框架之一,作为JavaEE程序员,在工作中不可能不用到mybatis.所以为了工作,为了学习,为了个人的发展,每个JavaEE程序员都要学习,学会mybatis ...

  7. HDU 3085 Nightmare Ⅱ(噩梦 Ⅱ)

    HDU 3085 Nightmare Ⅱ(噩梦 Ⅱ) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  8. 浅谈Cocos2d-js ListView滑动防止误触

    Event背景 最近,接到一个需求,优化房间内设置界面: 表面问题:用户在按钮表面,滑动界面的时候,总会误触到界面上的按钮或者复选框 根本问题:由于ListView的事件具有传递性,导致双重事件触发, ...

  9. [Windows]卸载Office 2016密钥

    cscript "C:\Program Files (x86)\Microsoft Office\Office16\ospp.vbs" /dstatus BTDRB

  10. Shopping List

    剃须啫喱 吉列 70g $22.00 鲁阳家居专营店 剃须水套装 阿帕奇+酷曼 230g+230g $16.80(限时活动) 鲁阳家居专营店 鸡胸肉 撸铁党 100gx9+100g $49.9(限时活 ...