图的遍历(dfs)

【题目描述】

对于一个有向图G来说,我们存在一个经典的遍历算法,就是DFS (深度优先搜索遍历)。将G以1号点为起点进行DFS后,我们可以 得到G的一棵DFS遍历树T。就此,我们可以把G中的所有边分成4种 类型,如下: • 树边:边(u,v)满足是T上的边。 • 返祖边:边(u,v)满足在T上v是u的祖先。 • 前向边:边(u,v)满足在T上u是v的祖先,但不是父亲(即不是 树边)。 • 横叉边:除去以上所有情况的边就是横叉边。 现在我们给出四个整数A,B,C,D,要求构造图G,使得对G以1号点开 始进行DFS后,树边个数为A,返祖边个数为B,前向边个数为C,横 叉边个数为D。要求构造的G满足,联通(可以从1号点出发到达其他 所有点)、无重边、无自环,否则视为不合法。你只需要输出其中 任意一个解即可,我们会用spj判断你的解是否合法。

【输入格式】

仅一行,四个整数,表示 A,B,C,D。

【输出格式】

如果不存在解,输出-1。 如果有解,请现在第一行输出一个整数N,表示G的点数。 接下来N行,第i行先输出一个数Degreei,表示第i个点的出度; 接下来输出Degreei个数,描述i的所有出边。 注意不能存在重边和自环。 请注意,对于点i,在DFS过程中,我们会根据你输出的边的顺序, 依次进行拓展。

【样例输入】

3 1 1 1

【样例输出】

4

3 2 4 3

1 3

1 1

1 2

【数据范围】

本题一共 10 个测试点,每个测试点分值为 10 分。测试数据可分为 6 个部分,具体分值和说明如下: • 10% 的数据满足:0≤A,B,C,D≤5。 • 10% 的数据满足:D=0 • 10% 的数据满足:B=C=0。 • 20% 的数据满足:A≤100。 • 20% 的数据满足:A≤1000。 • 30% 的数据满足:A≤100000。 对于 100%的数据, 满足 0≤A,B,C,D≤100000。

sol:(题解)树边+前向边和返祖边数量是等价的,两者取最大即可称为 X 类 边,极端情况是链,共 N*(N-1)/2 条 但横叉边与上面俩是互斥的,称为 Y 类边,极端情况是菊花,共 (N-1)*(N-2)/2 条 考虑把菊花的一个叶子挪到某个叶子下面,发现 Y 类边少了一 条,X 类边多了一条。链类似 于是可以判断无解的情况,即 X 类边+Y 类边>N*(N-1)/2 yy 横叉边有点奇怪,考虑构造 X 类边刚好的方案,那么之后能 连得横叉边数量是最多的,一定满足 进一步观察,一个点能贡献 X 类边的数量之和它的深度有关,于 是直接先搞条链,最后一个点深度刚好卡好,接下来全都是深度为 1 的叶子即可 有其他构造方案的同学可以上来交流一下

自己yy的:说人话,应该已经知道链加菊花会是最优的,然后先在一条链上凑到max(A+C,B),剩下的搞成菊花

建边的时候dfs下去,注意一下顺序即可

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{ll s=0;bool f=0;char ch=' ';while(!isdigit(ch)){f|=(ch=='-'); ch=getchar();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{if(x<0){putchar('-'); x=-x;}if(x<10){putchar(x+'0'); return;}write(x/10);putchar((x%10)+'0');return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=100005;
int n,A,B,C,D,X,Y,Id[N],Top,Father[N],Lower[N];
//树边个数为A,返祖边个数为B,前向边个数为C,横叉边个数为D
vector<int>E[N],Ans[N];
inline void Link(int u,int v)
{E[u].push_back(v); Ans[u].push_back(v);
}
inline void dfs(int u)
{int i,j;for(i=1;i<=E[u].size();i++){int v=E[u][i-1];Father[v]=u;if(C){for(j=Father[u];j&&C;j=Father[j]){Ans[j].push_back(v); C--; if(!C) break;}}if(B){for(j=u;j&&B;j=Father[j]){Ans[v].push_back(j); B--; if(!B) break;}}if(D){for(j=1;j<=*Lower;j++){Ans[v].push_back(Lower[j]); D--; if(!D) break;}}dfs(v);}Lower[++*Lower]=u;
}
int main()
{freopen("dfs.in","r",stdin);freopen("dfs.out","w",stdout);int i,j,Sum;R(A); R(B); R(C); R(D);Sum=X=max(B,A+C); Y=D; n=A+1;if((long long)(1LL*n*(n-1)/2)<(long long)(X+Y)) return puts("-1"),0;Id[Top=0]=1;for(i=2;i<=n;i++){if(Sum>=Top+1+n-i){Link(Id[Top++],i); Sum-=Top; Id[Top]=i;}else{int tmp=Sum-(n-i); Link(Id[tmp-1],i); Sum-=tmp;}}dfs(1);Wl(n);for(i=1;i<=n;i++){W((int)Ans[i].size());for(j=1;j<=Ans[i].size();j++) W(Ans[i][j-1]);putchar('\n');}return 0;
}
/*
input
3 1 1 1
output
4
3 2 4 3
1 3
1 1
1 2
*/

View Code

转载于:https://www.cnblogs.com/gaojunonly1/p/11167166.html

7.9模拟赛T1图的遍历(dfs)相关推荐

  1. 洛谷 10月 csp-s 模拟赛 T1,T2解析及代码

    洛谷 10月 csp-s 模拟赛 T1,T2解析及代码 T1 Magenta Potion 题目描述 给定一个长为 nnn 的整数序列 aaa,其中所有数的绝对值均大于等于 222.有 qqq 次操作 ...

  2. (王道408考研数据结构)第六章图-第三节:图的遍历(DFS和BFS)

    文章目录 一:图的深度优先遍历(DFS) (1)回溯算法和DFS A:回溯算法的本质 B:回溯算法的框架 C:全排列 (2)图的DFS A:DFS思想 B:动画演示 C:代码 二:图的广度优先遍历(B ...

  3. 数据结构 --- 图的遍历 DFS、BFS

    什么是DFS.BFS? 一条线走到底,深度优先遍历,每一个顶点只遍历.只打印一次的方式:DFS.BFS 数据结构 --- 图的存储 单纯地把邻接顶点的邻接顶点打印出来,顶点重复遍历,打印多次 从 A→ ...

  4. Java 第十一届 蓝桥杯 省模拟赛 小明植树(DFS)

    小明植树 题目 问题描述 小明和朋友们一起去郊外植树,他们带了一些在自己实验室精心研究出的小树苗. 小明和朋友们一共有 n 个人,他们经过精心挑选,在一块空地上每个人挑选了一个适合植树的位置,总共 n ...

  5. 图的遍历(DFS和BFS)

    图的遍历是指从图中某一顶点出发,访遍图中其余顶点,且使每一个顶点仅被访问一次. 一.深度优先遍历(Depth First Search) 假设给定图G的初态是所有顶点均未曾访问过.在G中任选一顶点v为 ...

  6. 纪中20日c组模拟赛T1 2121. 简单游戏

    T1 2121. 简单游戏 (File IO): input:easy.in output:easy.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 Goto Pro ...

  7. 【2019.7.16 NOIP模拟赛 T1】洗牌(shuffle)(找环)

    找环 考虑每次洗牌其实是一次置换的过程,而这样必然就会有循环出现. 因此我们直接通过枚举找出每一个循环,询问时只要找到环上对应的位置就可以了. 貌似比我比赛时被卡成\(30\)分的倍增简单多了? 代码 ...

  8. 20161023 NOIP 模拟赛 T1 解题报告

    Task 1.纸盒子 (box.pas/box.c/box.cpp) [题目描述] Mcx是一个有轻度洁癖的小朋友.有一天,当他沉溺于数学卷子难以自拔的时候,恍惚间想起在自己当初学习概率的时候准备的一 ...

  9. 2019-3-15 模拟赛 T1

    题意 给你一个数 \(k\) ,\(n\) 个桶,有 \(m\) 个桶有容量上限 \(w_i\) ,其它桶则没有.求把数拆开放到各个桶里,最终得到序列的方案数. 数据范围 : \(n,k<=5* ...

最新文章

  1. 2021年大数据Kafka(五):❤️Kafka的java API编写❤️
  2. word 语音识别的数据丢失
  3. python 编码规范 PEP8整理
  4. sdcard不可执行.
  5. 使用ABAP(ADBC)和Java(JDBC)连接SAP HANA数据库
  6. 电子信息工程水声考研去向_哈工大电子与信息工程专业考研 科研方向汇总
  7. 解决Genymotion运行Android 5.0一直卡在开机界面
  8. android之微信分享音频
  9. Knockoutjs官网翻译系列(一)
  10. mii-tool与ethtool的用法详解
  11. java薪资年龄交叉表_巧用参数实现交叉表行列互换
  12. x-lite for linux,Linux Lite 4.6正式发布:现基于Ubuntu 18.04.3 LTS
  13. 树莓派C语言点灯,树莓派3 b GPIO 点亮小灯泡
  14. Asp.net SignalR
  15. 下载的代码找不到rt.jar中的类
  16. Message Queue基本使用说明
  17. Linux Tomcat9 控制界面及管理配置
  18. php net-snmp trap,什么是正确的snmptrap命令格式?
  19. 开发老铁们,就参考这个图灵畅销新书书单加购!
  20. [KALI] 开启ssh远程连接

热门文章

  1. 原版英文书籍《Linux命令行》阅读记录4 | 操作文件和目录
  2. 小程序问题记录:小程序云开发获取不到数据库的记录
  3. LINQ to DataSet
  4. 机器人驾驶的神经网络愿景(下)
  5. Opencv--获取Mat图像数据的方式
  6. OPenCV的中cvErode和cvDilate腐蚀和膨胀函数
  7. 腾讯云对象存储 python_GitHub - fushall1104/cos-python3-sdk: 腾讯云对象存储服务(cos)Python3.5版本SDK...
  8. arduino步进电机程序库_Arduino基础入门篇27—步进电机驱动库的使用
  9. python动态与静态语言_静态语言和动态语言的区别
  10. div内容横排 html_css如何让文字横向滑入?