CF1103C Johnny Solving(构造题)
2021/9/22 23:12:03
本文主要是介绍CF1103C Johnny Solving(构造题),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
洛谷传送门
解题思路
在图上很难做这种构造题,所以一种常用的方法是求出其生成树。
在生成树上做就容易很多。
于是这个题就按照 dfs 序建立一颗生成树,记录下每个节点的返祖边。
于是第一问可以根据树的深度判断是否符合要求,符合的话直接输出。
若没有,则易证第二问一定成立:
因为第一问不成立,所以叶子节点数一定 \(\geqslant k\),而题中保证每个节点的度数 \(\geqslant3\),也就暗示了叶子节点都有 \(\geqslant2\) 条返祖边。
所以一定能从每个叶子节点找到一个符合要求的环。
假设叶子节点 k 的两个返祖祖先为 x 和 y,则通过作差法易证:
\((dep[u]-dep[x]+1)\) 和 \((dep[u]-dep[y]+1)\) 和 \((dep[y]-dep[x]+2)\) 中至少有一个不是 \(3\) 的倍数。
判断一下输出即可。
注意
数组一定要开够:大小为 m 的两倍!否则会在第四个点TLE。
AC代码
#include<cstdio> #include<iostream> #include<cstring> #include<iomanip> #include<cmath> #include<algorithm> using namespace std; const int maxn=5e5+5; int n,m,k,cnt,cnt_leaf,leaf[maxn],p[maxn],dep[maxn],fa[maxn],ancestor[maxn][105]; int maxdep,ed; template <typename T> inline void read(T &x) { char c; x=0; int fu=1; c=getchar(); while(c>57||c<48){ if(c==45){ fu=-1; } c=getchar(); } while(c<=57&&c>=48) { x=(x<<3)+(x<<1)+c-48; c=getchar(); } x*=fu; } struct node{ int v,next; }e[maxn*2]; void insert(int u,int v){ cnt++; e[cnt].v=v; e[cnt].next=p[u]; p[u]=cnt; } void dfs(int u,int f,int deep){ dep[u]=deep; if(dep[u]>maxdep){ maxdep=dep[u]; ed=u; } fa[u]=f; leaf[++cnt_leaf]=u; for(int i=p[u];i!=-1;i=e[i].next){ int v=e[i].v; if(v==f) continue; if(dep[v]){ ancestor[u][++ancestor[u][0]%100]=v; continue; } if(leaf[cnt_leaf]==u) cnt_leaf--; dfs(v,u,deep+1); } } void print(int u,int to){ printf("%d ",to); if(u==to) return; print(u,fa[to]); } int main(){ memset(p,-1,sizeof(p)); read(n); read(m); read(k); for(int i=1;i<=m;i++){ int u,v; read(u); read(v); insert(u,v); insert(v,u); } dfs(1,-1,1); if(maxdep>=(n-1)/k+1){ puts("PATH"); printf("%d\n",maxdep); while(ed!=-1){ printf("%d ",ed); ed=fa[ed]; } return 0; } puts("CYCLES"); for(int i=1;i<=k;i++){ int u=leaf[i],x=ancestor[u][1],y=ancestor[u][2]; if(dep[x]>dep[y]) swap(x,y); if((dep[u]-dep[x]+1)%3!=0){ printf("%d\n",dep[u]-dep[x]+1); print(x,u); puts(""); }else{ if((dep[u]-dep[y]+1)%3!=0){ printf("%d\n",dep[u]-dep[y]+1); print(y,u); puts(""); }else{ printf("%d\n%d ",dep[y]-dep[x]+2,u); print(x,y); puts(""); } } } return 0; }
这篇关于CF1103C Johnny Solving(构造题)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-12深入理解 ECMAScript 2024 新特性:Map.groupBy() 分组操作
- 2025-01-11国产医疗级心电ECG采集处理模块
- 2025-01-10Rakuten 乐天积分系统从 Cassandra 到 TiDB 的选型与实战
- 2025-01-09CMS内容管理系统是什么?如何选择适合你的平台?
- 2025-01-08CCPM如何缩短项目周期并降低风险?
- 2025-01-08Omnivore 替代品 Readeck 安装与使用教程
- 2025-01-07Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
- 2025-01-06PingCAP 连续两年入选 Gartner 云数据库管理系统魔力象限“荣誉提及”
- 2025-01-05Easysearch 可搜索快照功能,看这篇就够了
- 2025-01-04BOT+EPC模式在基础设施项目中的应用与优势