将相邻且颜色相同的点视作一个连通块,若该连通块是二分图,那么从连通块中一点\(x\)到连通块中一点\(y\)的路径的奇偶性确定

所以对于块外一点\(x\)到块内一点\(y\),可以将它们的路径在连通块内的部分看作在一条边上反复横跳(这样奇偶性不变且当路径长度不够时可以凑长度),然后决定是否走出这条边而走向下一条边

所以在二分图中,环没有必要存在,只需要它的最小生成树即可(二分图的环的作用就是凑长度,而反复横跳一条边也可以达成这一目的,且二者都不会改变奇偶性)

若不是连通块,也就是存在奇环,那么奇偶性就会发生变化(奇环走一圈),所以奇环不能用反复横跳来替代

所以在非二分图的连通块中,我们只需要保留一个奇环即可,而为了方便,我们可以随机给一个节点连一条自环

  1. #include<bits/stdc++.h>
  2. #define pr pair<int,int>
  3. #define fi first
  4. #define se second
  5. using namespace std;
  6. const int N=5e3+5,M=5e5+5,MN=1e6+5e3+5;
  7. int n,m,Q;
  8. char s[N];
  9. int head[N],cnt;
  10. struct node{
  11. int v,nxt;
  12. }tree[MN];
  13. void add(int x,int y){
  14. tree[++cnt].v=y,tree[cnt].nxt=head[x],head[x]=cnt;
  15. }
  16. vector<int> edge[N];
  17. bool flag[N][N];
  18. queue<pr> q;
  19. void add1(int x,int y){
  20. flag[x][y]=flag[y][x]=1,q.push(pr(x,y));
  21. }
  22. int color[N];
  23. bool f;
  24. void dfs(int x,int now){
  25. color[x]=now;
  26. for(int i=0,y;i<edge[x].size();++i){
  27. y=edge[x][i];
  28. if(s[x]==s[y]){
  29. if(color[x]==color[y]) f=true;
  30. if(color[y]!=-1) continue;
  31. add1(x,y),add(x,y),add(y,x);
  32. dfs(y,now^1);
  33. }
  34. }
  35. }
  36. bool vis[N];
  37. void dfs1(int x){
  38. vis[x]=true;
  39. for(int i=0,y;i<edge[x].size();++i){
  40. y=edge[x][i];
  41. if(s[x]!=s[y]&&!vis[y]) add(x,y),add(y,x),dfs1(y);
  42. }
  43. }
  44. void solve(){
  45. int x,y;
  46. while(q.size()){
  47. x=q.front().fi,y=q.front().se,q.pop();
  48. for(int i=head[x],x1;i;i=tree[i].nxt)
  49. for(int j=head[y],y1;j;j=tree[j].nxt){
  50. x1=tree[i].v,y1=tree[j].v;
  51. if(s[x1]==s[y1]&&!flag[x1][y1]) add1(x1,y1);
  52. }
  53. }
  54. }
  55. int main(){
  56. scanf("%d%d%d",&n,&m,&Q);
  57. getchar(); cin>>s+1;
  58. for(int i=1,u,v;i<=m;++i) scanf("%d%d",&u,&v),edge[u].push_back(v),edge[v].push_back(u);
  59. for(int i=1;i<=n;++i) add1(i,i),color[i]=-1;
  60. for(int i=1;i<=n;++i){
  61. f=false;
  62. if(color[i]!=-1) continue;
  63. dfs(i,1);
  64. if(f) add(i,i);
  65. }
  66. for(int i=1;i<=n;++i) if(!vis[i]) dfs1(i);
  67. solve();
  68. while(Q--){
  69. int u,v; scanf("%d%d",&u,&v);
  70. printf(flag[u][v]?"YES\n":"NO\n");
  71. }
  72. return 0;
  73. }

「HNOI2019」校园旅行的更多相关文章

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

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

  2. LOJ 3057 「HNOI2019」校园旅行——BFS+图等价转化

    题目:https://loj.ac/problem/3057 想令 b[ i ][ j ] 表示两点是否可行,从可行的点对扩展.但不知道顺序,所以写了卡时间做数次 m2 迭代的算法,就是每次遍历所有不 ...

  3. 「loj3057」「hnoi2019」校园旅行

    题目 一个n个点m条边的无向图,每个点有0 / 1 的标号; 有q个询问,每次询问(u,v)直接是否存在回文路径(可以经过重复的点和边); $1 \le n \le 5 \times 10^3  , ...

  4. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  5. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  6. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  7. Loj 3058. 「HNOI2019」白兔之舞

    Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...

  8. [LOJ3054] 「HNOI2019」鱼

    [LOJ3054] 「HNOI2019」鱼 链接 链接 题解 首先想 \(O(n^3)\) 的暴力,不难发现枚举 \(A\) 和 \(D\) 后, \((B,C)\) 和 \((E,F)\) 两组点互 ...

  9. 【loj - 3056】 「HNOI2019」多边形

    目录 description solution accepted code details description 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时 ...

  10. 【loj - 3055】「HNOI2019」JOJO

    目录 description solution accepted code details description JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或 ...

随机推荐

  1. Kubeadm部署Kubernetes

    Kubeadm部署Kubernetes 1.环境准备 主机名 IP 说明 宿主机系统 k8s-master 10.0.0.101 Kubernetes集群的master节点 Ubuntu2004 k8 ...

  2. Python基础之模块:2、包的使用和软件开发目录规范及常用内置模块

    目录 一.包的使用 1.什么是包 2.包的具体使用 1.常规导入 2.直接导入包名 二.编程思想转变 1.面条阶段 2.函数阶段 3.模块阶段 三.软件目录开发规范 1.bin 2.conf 3.co ...

  3. 【翻译】Spring Security抛弃了WebSecurityConfigurerAdapter

    原文链接:Spring Security without the WebSecurityConfigurerAdapter 作者:ELEFTHERIA STEIN-KOUSATHANA 发表日期:20 ...

  4. elasticsearch聚合之bucket terms聚合

    目录 1. 背景 2. 前置条件 2.1 创建索引 2.2 准备数据 3. 各种聚合 3.1 统计人数最多的2个省 3.1.1 dsl 3.1.2 运行结果 3.2 统计人数最少的2个省 3.2.1 ...

  5. K8s集群环境搭建

    K8s集群环境搭建 1.环境规划 1.1 集群类型 Kubernetes集群大体上分为两类:一主多从和多主多从 一主多从:一台master节点和多台node节点,搭建简单,但是有单机故障风险,适用于测 ...

  6. 【云原生 · Kubernetes】kubernetes v1.23.3 二进制部署(一)

    kubernetes v1.23.3 二进制部署 1. 组件版本和配置策略 1.1 主要组件版本 1.2 主要配置策略 2. 初始化系统和全局变量 2.1 集群规划 2.2 kubelet cri-o ...

  7. 使用lamdba查询datatable中的一个值或者单元格

    首先创建一个datatable,结构简单的分为两列 Datatable dt=new Datatable(); dt.Columns("code"); dt.Columns(&qu ...

  8. Linux下用rm误删除文件的三种恢复方法

    Linux下用rm误删除文件的三种恢复方法 对于rm,很多人都有惨痛的教训.我也遇到一次,一下午写的程序就被rm掉了,幸好只是一个文件,第二天很快又重新写了一遍.但是很多人可能就不像我这么幸运了.本文 ...

  9. html网页图片加载失败的友好处理方式

    网络环境总是多样且复杂的,一张网页图片可能会因为网路状况差而加载失败或加载超长时间,也可能因为权限不足或者资源不存在而加载失败,这些都会导致用户体验变差,所以我们需要对图片加载失败时的情况进行一个弥补 ...

  10. python字符串常用方法介绍,基于python3.10

    python字符串常用方法-目录: 1.strip().lstrip().rstrip()2.removeprefix().removesuffix()3.replace()4.split().rsp ...