非常妙的一道思博题啊,不愧是myy出的题

首先我们考虑一个暴力DP,直接开一个数组\(f_{i,j}\)表示\(i\to j\)的路径能否构成回文串

考虑直接拿一个队列来转移,队列里存的都是\(f_{i,j}=1\)的点对,然后每次枚举两边的边更新答案并扩展即可

但是这样的复杂度是\(O(m^2)\)的,不够优秀。我们发现其实这种方法的复杂度瓶颈在于有很多无用边导致我们浪费了复杂度,因此我们考虑删去一些边

我们首先在原图上把所有同色点间的边连起来,由于每个点可以经过任意次,因此我们只需要考虑奇偶性

那么什么时候能让到一个点的奇偶性改变呢?其实很简单,就是存在奇环

我们再进一步思考,如果一个图没有奇环,那么它就是二分图,而二分图的一个生成树显然也满足如上的性质

那么也就意味着,如果此时构成的图是二分图,那么我们求出它的生成树即可

但是如果不是呢,其实也很简单,我们考虑最简单的奇环是什么,其实就是自环

所以这种情况我们可以直接找一个点给它连一个自环帮助转移即可

那么剩下的只有异色点之间的边了,这个由于它都帮你染色好了,所以必然是二分图,直接求生成树即可

综上,此时的边数只有\(O(n)\)级别,因此总复杂度就是\(O(n^2)\)

CODE

#include<cstdio>
#include<utility>
#include<cstring>
#define RI register int
#define CI const int&
#define Ms(f,x) memset(f,x,sizeof(f))
using namespace std;
const int N=5005,M=500005;
typedef pair <int,int> pi;
struct edge
{
int to,nxt;
}e[M<<1],ne[M<<1]; bool f[N][N],flag; pi q[N*N];
char s[N]; int n,m,t,H,T,head[N],nhead[N],cnt,x,y,col[N];
inline void addedge(CI x,CI y)
{
e[++cnt]=(edge){y,head[x]}; head[x]=cnt;
e[++cnt]=(edge){x,head[y]}; head[y]=cnt;
}
inline void nadd(CI x,CI y)
{
ne[++cnt]=(edge){y,nhead[x]}; nhead[x]=cnt;
}
inline void push(CI x,CI y)
{
f[x][y]=f[y][x]=1; q[++T]=make_pair(x,y);
}
#define to e[i].to
inline void DFS(CI now,CI tp)
{
for (RI i=head[now];i;i=e[i].nxt) if ((s[now]==s[to])==tp)
{
if (~col[to]) { if (col[to]==col[now]) flag=0; }
else col[to]=col[now]^1,DFS(to,tp),nadd(now,to),nadd(to,now);
}
}
#undef to
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i,j; for (scanf("%d%d%d%s",&n,&m,&t,s+1),i=1;i<=m;++i)
scanf("%d%d",&x,&y),addedge(x,y),s[x]==s[y]&&(push(x,y),0); cnt=0; Ms(col,-1);
for (i=1;i<=n;++i) if (!~col[i]&&(col[i]=flag=1,DFS(i,1),!flag)) nadd(i,i);
for (Ms(col,-1),i=1;i<=n;++i) if (!~col[i]) col[i]=1,DFS(i,0);
for (i=1;i<=n;++i) push(i,i); while (H<T)
{
++H; int x=q[H].first,y=q[H].second;
for (i=nhead[x];i;i=ne[i].nxt) for (j=nhead[y];j;j=ne[j].nxt)
if (s[ne[i].to]==s[ne[j].to]&&!f[ne[i].to][ne[j].to]) push(ne[i].to,ne[j].to);
}
while (t--) scanf("%d%d",&x,&y),puts(f[x][y]?"YES":"NO"); return 0;
}

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

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

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

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

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

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

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

  4. [HNOI2019]校园旅行

    题意 https://www.luogu.org/problemnew/show/P5292 思考 最朴素的想法,从可行的二元组(u,v)向外拓展,及u的出边所指的颜色与v的出边所指的颜色若相同,继续 ...

  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. capwap学习笔记——初识capwap(四)(转)

    2.5.7 CAPWAP传输机制 WTP和AC之间使用标准的UDP客户端/服务器模式来建立通讯. CAPWAP协议支持UDP和UDP-Lite [RFC3828]. ¢ 在IPv4上,CAPWAP控制 ...

  2. Android的JDK、SDK、Eclipse的理解

    今天看了这方面的内容,感觉学到了一些东西: 首先,jdk是用来处理Java语言的, sdk是用来处理Java语言和硬件之间的关联的, eclipse是用来编写Java语言的, 通过对这方面的理解,加深 ...

  3. Android 超高仿微信图片选择器 图片该这么加载

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39943731,本文出自:[张鸿洋的博客] 1.概述 关于手机图片加载器,在当今像 ...

  4. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

  5. linux学习之路(2)

    1.输入输出重定向  输入重定向中用到的符号及其作用 命令 < 文件 将文件作为命令的标准输入 命令 << 分界符 从标准输入中读入,直到遇见分界符才停止 命令 < 文件 1 ...

  6. IOS-QQ第三方登录

    iOS QQ第三方登实现   我们经常会见到应用登陆的时候会有QQ,微信,微博等的第三方登陆 如图: 下面我们主要讲一下qq的第三方登陆如何实现 首先,到官网注册: http://wiki.conne ...

  7. Python&Appium实现滑动引导页进入APP

    最近在研究安卓APP的自动化测试.首先遇到的问题是,当一个session建立的时候,最先进入的是欢迎页和引导页,引导页有三张,最后一张上显示"enter"按钮,点击才能进入主界面. ...

  8. 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传

    准备工作: 建立.NET Core Web Api项目 新建一个用于Api请求的UserInfo类 public class UserInfo { public string name { get; ...

  9. 异步处理,Event Souring,事务补偿,实现最终一致性和服务的弹性和批处理

    这段时间一直学习极客时间皓哥的分布式架构,关于异步处理有一些感想用sketch做了一个图,展示上直观一些,和大家交流下

  10. 将wiki人脸数据集的性别信息提取出来制作标签

    import scipy.io as scio dataFile = 'D:\\Users\\a\\Documents\\Tencent Files\\178026882\\FileRecv\\wik ...