题目

过于神仙啊,抄题解.jpg

首先\(n\)并不是很大啊,我们可以直接用\(f_{i,j}\)表示\(i\)到\(j\)是否存在一个回文路径

对于一条回文路径,如果在两端分别添加一个相同的字符,那么仍然是一个回文路径,于是我们可以利用这个来打一个暴力\(bfs\)

就像这样

while(!q[0].empty()) {int x=q[0].front(),y=q[1].front();q[0].pop(),q[1].pop();for(re int i=0;i<v[x].size();i++)for(re int j=0;j<v[y].size();j++) {int xx=v[x][i],yy=v[y][j];if(xx>yy) std::swap(xx,yy);if(S[xx]!=S[yy]||f[xx][yy]) continue;f[xx][yy]=dp[xx][yy]=1;q[0].push(xx),q[1].push(yy);}}

非常显然这个复杂度一点也不科学,卡满就是\(O(m^2)\)的,肯定是要\(T\)的

但是\(n\)却不是很大,能不能让边数减小一点呢

之后就不会啦,愉快地抄题解

首先我们注意到一个问题,就是我们只需要关注奇偶性就好了,因为我们可以来回走一条边使得长度增加,但是并不能改变奇偶性

之后我也不知道为什么通过这一点就想到了二分图

我们把边分成两类,一类是连接相同颜色点的边,一类是连接不同颜色点的边

我们考虑一个连通块,这个连通块仅由相同颜色的点构成,显然这个连通块里的边都是第一类边

如果这个连通块是一个二分图,由于二分图不存在奇环,对于任意两个点,所有连接这两个点的路径的奇偶性都是一样的

由于我们也只关注奇偶性,所以只需要对这个二分图搞出来一棵生成树即可

如果这个联通块不是一个二分图,那么就一定存在至少一个奇环,那么我们就可以通过走这个奇环使得路径的奇偶性改变

我们需要让边的数量尽量少,那么只需要求出来一棵有奇环的基环树即可

这些我们都能通过\(dfs\)来完成

对于第二类边,只考虑这些边的话整张图就是一个二分图,于是我们还是对这些边求一个生成树即可

最后我们发现我们这张图的边数已经和\(n\)同级了,于是我们直接上最开始的那个暴力,复杂度就是\(O(n^2)\)了

代码

#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
inline int read() {char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=5e3+5;
std::vector<int> v[maxn];
std::queue<int> q[2];
struct E{int v,nxt;}e[1000005];
int n,m,Q,num,tot,flag;
char S[maxn];
int f[maxn][maxn],dp[maxn][maxn],vis[maxn],fa[maxn],sz[maxn],pre[maxn];
int head[maxn],a[500005],b[500005];
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
void dfs(int x,int fa) {vis[x]=1;for(re int i=head[x];i;i=e[i].nxt) {if(S[e[i].v]!=S[x]||fa==e[i].v) continue;if(vis[e[i].v]&&S[e[i].v]==S[x]&&!flag) {if(!(pre[e[i].v]^pre[x])) v[x].push_back(e[i].v),v[e[i].v].push_back(x),flag=1;continue;}v[x].push_back(e[i].v);v[e[i].v].push_back(x);pre[e[i].v]=pre[x]^1;dfs(e[i].v,x);}
}
inline int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void merge(int x,int y) {if(sz[x]<sz[y]) fa[y]=x,sz[y]+=sz[x];else fa[x]=y,sz[x]+=sz[y];
}
int main() {n=read(),m=read(),Q=read();scanf("%s",S+1);for(re int x,y,i=1;i<=m;i++) {x=read(),y=read(),add(x,y),add(y,x);if(S[x]!=S[y]) a[++tot]=x,b[tot]=y;}for(re int i=1;i<=n;i++) {if(vis[i]) continue;flag=0;dfs(i,0);}for(re int i=1;i<=n;i++) fa[i]=i,sz[i]=1;for(re int i=1;i<=tot;i++) {int xx=find(a[i]),yy=find(b[i]);if(xx==yy) continue;merge(xx,yy);v[a[i]].push_back(b[i]);v[b[i]].push_back(a[i]);}for(re int i=1;i<=n;i++) f[i][i]=dp[i][i]=1,q[0].push(i),q[1].push(i);for(re int i=1;i<=n;i++) for(re int j=0;j<v[i].size();j++) {int x=i,y=v[i][j];if(x>y) std::swap(x,y);if(S[x]!=S[y]||f[x][y]) continue;f[x][y]=dp[x][y]=1,q[0].push(x),q[1].push(y);}while(!q[0].empty()) {int x=q[0].front(),y=q[1].front();q[0].pop(),q[1].pop();for(re int i=0;i<v[x].size();i++)for(re int j=0;j<v[y].size();j++) {int xx=v[x][i],yy=v[y][j];if(xx>yy) std::swap(xx,yy);if(S[xx]!=S[yy]||f[xx][yy]) continue;f[xx][yy]=dp[xx][yy]=1;q[0].push(xx),q[1].push(yy);}}for(re int x,y,i=1;i<=Q;i++) {x=read(),y=read();if(x>y) std::swap(x,y);puts(dp[x][y]?"YES":"NO");}return 0;
}

转载于:https://www.cnblogs.com/asuldb/p/10803482.html

[HNOI2019]校园旅行相关推荐

  1. luogu P5292 [HNOI2019]校园旅行

    传送门 首先考虑暴力M^2dp,考虑回文串是可以从回文中心每次在两边拓展的,设\(f_{i,j}\)为\(i\)到\(j\)的路径是否是回文串,bfs转移,枚举两点出边,如果两个新端点颜色相同就更新 ...

  2. 【HNOI2019】部分题简要题解

    题意懒得写了 LOJ Day 1 T1 鱼 个人做法比较猎奇,如果有哪位大佬会证明能分享一下的话感激不尽. 题解:枚举鱼尾和鱼身的交点D,将所有其他点按照到D的距离排序,距离相同的分一组. 感性的理解 ...

  3. 项目评测(共27组)

    第一组:生活日历 1.界面设计绿色和蓝色配比需要提升,界面风格不太统一 2.日历日程和账单功能基本实现 3.模拟机展示输入功能不太完善,其真机调试情况不明 4.可以仿照闹钟,设置事件提醒 第二组:计一 ...

  4. 星辰小组——第一阶段评分+各小组的意见反馈

    日期:2019.5.27 博客期:085 星期一 今天我们终于完成了对于冲刺第一阶段的小组成员评分! 评分结果如下: 用户评价 1. 第一组(oneteam,生活日历):app开发.以日历作为核心功能 ...

  5. pmp访谈法和焦点小组区别_时间,空间和访谈

    pmp访谈法和焦点小组区别 像大多数软件公司一样,Microsoft几乎所有的技术面试都涉及某种编码问题. 在那期间,我遇到了许多不同的问题. 它们通常都具有您可以很好地讨论一般问题空间,设计解决方案 ...

  6. 只有高中学历的我是怎样加入谷歌的?

    昨天谷歌 AlphaGo 战胜了围棋顶尖高手还是出乎很多人意料之外,相信大家都被刷屏了,朋友圈久久不能平复,今天就不谈围棋,谈人生.本文是讲了一个有趣的个人经历,一个高中生学历的人通过自己努力成为谷歌 ...

  7. 多地通知!防止疫情反扑将控制教职工和学生外出,新一轮校园封闭要开始了?...

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 本文来源:募格学术整合自中国青年报.宁波教育.都匀微教育陕西都市快报.募格课堂等. 导读: 近期,全国 ...

  8. 钉钉日志范文100篇_看图写话范文328:暑假旅行(4篇)

    范文01:暑假旅行400字 暑假,我们一家去了嘉兴游玩.嘉兴南湖因红船而成为革命圣地.老爸对于中国近代革命史可谓是如数家珍:"星星之火可以燎原!你们看,当初共产党就是在这么小的一艘船里点燃了 ...

  9. 校园导游java版,校园导游系统Word版

    <校园导游系统Word版>由会员分享,可在线阅读,更多相关<校园导游系统Word版(20页珍藏版)>请在人人文库网上搜索. 1.传播优秀Word版文档 ,希望对您有帮助,可双击 ...

最新文章

  1. iOS多线程中performSelector: 和dispatch_time的不同
  2. 分布式环境下的并发问题
  3. SpringBoot面向切面编程-用AOP方式管理日志
  4. SharePoint 2013 开发——其他社交功能
  5. 【HDU - 1263】 水果(STL)
  6. 怕入错行?这群技术人写了本“择业指南”
  7. Vue笔记-Ant Design Vue的使用(Vue3)
  8. 搭建高性能计算环境(七)、应用软件的安装之MS
  9. JSP ---- 入门
  10. 大数据-实时推荐系统最主流推荐系统itemCF和userCF视频教程下载
  11. 小学听课计算机笔记范文,小学听课笔记 范文大全
  12. 高斯公式_注解_高数
  13. “永远肩负守卫物联网安全的责任和使命”——Ayla CTO发声美网瘫痪事件
  14. 《别看了,你学不会的》——Redis原理与实战(一)
  15. Win10打开老游戏血战上海滩
  16. python计算财务指标,Python-股票-图表显示主要财务指标
  17. linux禁止中国使用方法,如果美国禁止软件系统,不让中国用Windows,中国何去何从?...
  18. MODIS数据几何校正(IDL)
  19. JavaScript开发数独游戏(一)
  20. 基于51单片机的水流量传感器测试系统

热门文章

  1. JavaScript/JS的学习
  2. Java中,我自己定义的某个类,去实现某个接口,是否必须实现该接口的全部抽象方法呢?
  3. MySQL 批量生成 SQL 脚本语句解决实际的业务需求/如何拼接字符串/拼接字符串的 SQL 语句
  4. python语句大全input_input提示文字 Python基础输入函数,if-else语句,if-elif
  5. 是否可以改变 宏的值_给女人的建议:当父母不同意你的男朋友,可以尝试六个方法...
  6. Linux内核链表访问链表头指针,linux内核——链表结构分析
  7. 归并排序 java_归并排序(Java实现)
  8. C++ inline 函数简介
  9. 对单片机C语言的一些误用和总结
  10. git rollback代码都没了_git回滚线上代码