题目大意

给定一个 $N$ 个点 $M$ 条边的有向图 $G$,无重边、自环。找出图 $G$ 的一个导出子图(induced subgraph) $G'$,且 $G'$ 中的每个点的入度和出度都是 1。

数据范围

  • $ 1 \le N \le 1000$
  • $ 0 \le M \le 2000$

分析

导出子图 $G'$ 中的每个点的入度和出度都是 1 相当于说 $G'$ 是一个(cycle)。

若不考虑 $G'$ 是导出子图这个条件,则可通过 DFS 判断图 $G$ 中是否有环,若有,同时还可以找出一个环。

下面给出环的一个性质:

若有向图 $C$ 是一个环,则往 $C$ 中添一条边将产生一个更小的环。

读者自证不难。

因此若有向图 $G$ 中有环,则 $G$ 中的最小环必然是 $G$ 的导出子图。

于是原问题可以转化成求图 $G$ 中的最小环。

更进一步,可以先在图 $G$ 上 DFS,找出一个环 $C$,设 $C$ 的点集是 $V_C$;接着在由 $V_C$ 导出的子图 $G_C$ 上找一个最小环 $C'$,则 $C'$ 是 $G_C$ 的导出子图,从而也是 $G$ 的导出子图。

上述论证用到了导出子图的一个性质:

若 $B$ 是 $A$ 的导出子图,$C$ 是 $B$ 的导出子图,则 $C$ 也是 $A$ 的导出子图。

Implementation

下列代码是最暴力的实现。

  1. int n, m; scan(n, m);
  2. if (n == 1) {
  3. println(-1);
  4. return 0;
  5. }
  6. vv<int> g(n);
  7. rep (m) {
  8. int a, b; scan(a, b); --a, --b;
  9. g[a].pb(b);
  10. }
  11. vb used(n);
  12. vb vis(n);
  13. int lim;
  14. int root;
  15. bool flag;
  16. function<void(int,int)> dfs = [&](int u, int d) {
  17. vis[u] = true;
  18. if (d == lim) {
  19. FOR (v, g[u]) {
  20. if (v == root) {
  21. flag = true;
  22. println(d + 1);
  23. break;
  24. }
  25. }
  26. }
  27. else {
  28. FOR (v, g[u]) {
  29. if (!vis[v] && !used[v]) {
  30. dfs(v, d + 1);
  31. if (flag) break; // 别忘了这里的 break
  32. }
  33. }
  34. }
  35. if (flag) println(u + 1);
  36. };
  37. for (lim = 1; lim < n; ++lim) {
  38. fill(all(used), false);
  39. rng (i, 0, n) {
  40. fill(all(vis), false);
  41. flag = false;
  42. root = i;
  43. dfs(i, 0);
  44. if (flag) {
  45. return 0;
  46. }
  47. used[i] = true;
  48. }
  49. }
  50. println(-1);

【图论好题】ABC #142 Task F Pure的更多相关文章

  1. 11.07图论水题Test

    11.07图论水题Test 题目 描述 做法 \(BSOJ6378\) 在\(i\)位置可以到\(i+a_i\)或\(i+b_i\)求\(1\rightarrow n\)字典序最小路径 判可达性后贪心 ...

  2. 专题:CF图论杂题

    题目是来自HZW的博客(构造题我是各种不会...) Solved 1 / 1 A CodeForces 500A New Year Transportation Solved 1 / 1 B Code ...

  3. 《学习OpenCV》练习题第五章第二题abc

    代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...

  4. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  5. D9 图论综合题

    1.白银莲花池 LUOGU 2411 第一种思路:当然我们可以写三个bfs a掉这个题,这写下来一二百行要有了吧: 第二种:我们可以在一个bfs中维护所有的信息,一个方向数组,从起点开始,向八个方向扩 ...

  6. bzoj5109(图论好题)

    我的参考题解:https://www.cnblogs.com/ccz181078/p/7907022.html: 不过我感觉题解的压位有问题,(1<<x)还不炸上天.不过这题数据水,好像怎 ...

  7. 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解

    本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  8. 《学习OpenCV》练习题第四章第七题abc

    题外话:一直是打算把这本书的全部课后编程题写完的,中间断了几个月,一直忙于其他事.现在开始补上. 这道题我不清楚我理解的题意是不是正确的,这道题可以练习用OpenCV实现透视变换(可以用于矫正在3维环 ...

  9. 2014多校第一场D题 || HDU 4864 Task (贪心)

    题目链接 题意 : 用N台机器,M个任务,每台机器都有一个最大工作时间和等级,每个任务有一个需要工作时间和一个等级.如果机器完成一个任务要求是:机器的工作时间要大于等于任务的时间,机器的等级要大于等于 ...

随机推荐

  1. Vmware CentOS 7自适应屏幕分辨率

  2. 微信小程序_(组件)swiper轮播图

    微信小程序swiper轮播图组件官方文档 传送门 Learn: swiper组件 一.swiper组件 indicator-dots:是否显示面板指示点[默认值false] autoplay:是否自动 ...

  3. Linux 服务器安装jdk,mysql,tomcat简要教程

    linux服务器是阿里云上买的,学生价9.9/月,拿来学习下. 需要准备软件工具: 1.editplus (编辑服务器上的文件) 2.PuTTY (Linux命令连接器) 3.FlashFXP(上传文 ...

  4. redis 提供 6种数据淘汰策略

    淘汰策略的原因 在 redis 中,允许用户设置最大使用内存大小 server.maxmemory,在内存限定的情况下是很有用的.譬如,在一台 8G 机子上部署了 4 个 redis 服务点,每一个服 ...

  5. Mybatis 实体类使用@Accessors(chain = true)注解时,对应的mapper xml 报错

    去掉这个注解就行了 应该是 mybatis 会调用实体类的 getter  setter 方法, 返回值可能会有所影响

  6. VNC连接Ubuntu 16.04桌面灰色的问题解决

        1.安装gnome apt-get install --no-install-recommends ubuntu-desktop gnome-panel gnome-settings-daem ...

  7. vue 指示点的疑点拓展

    1. 为什么 vue 组件中的 data 是一个函数 1. 为了保证组件的独立性和可复用性,data 是一个函数,组件实例的时候,这个函数将会被调用,返回一个对象,计算机会给这个对象分配一个内存地址, ...

  8. 学习 vue 需要了解的内容

    总结 vue 的目录 1. vue 基础 指令 事件 动态的属性 组件 动画 2. vue 组件通信 1. 父传子 props 2. 子传父 ref 3. 插槽 4. 组件的生命周期 3. vue 的 ...

  9. koa 基础(五)动态路由的传值

    1.动态路由的传值 app.js /** * 动态路由的传值 */ // 引入模块 const Koa = require('koa'); const router = require('koa-ro ...

  10. vue类似tab切换的效果,显示和隐藏的判断。

    两者切换,动态显示对应的列表详情. 通过v-show的判断 数据驱动