传送门

题意:给定一张无向简单图,同时规定一条边只属于一个环。可以删除任意条边使得这张图变成森林,也就是使得每一个连通块都是树。求一共有多少种方案。

分析:由于原题规定一条边只属于一个环,不需要考虑环套环。每一种方案删除之后不能存在环,所以对于图中所有环,设环的边数为s,删除边的数量从1,2,3……s都是合法的,所以对于一个环的方案数为2^s-1。对于许多环,方案数相乘取模。同时,非环边可以任意删,所以求出所有环之后,设非环边数量为t,删除环边总方案为ans,删除非环边方案为2^t,则最后答案应当是2^t*ans。以上所有运算取模。

找环可以使用dfs一遍求出。方法为:vis数组设置为三种状态,0表示未被访问过。1表示正在被访问,即边指向的结点是当前结点在dfs树上的祖先节点。2表示访问完毕。同时dfs的同时记录每一个结点的先驱path。如果边访问到了vis为1的数组,说明存在环,则通过path数组,从当前结点回跳到指向的结点,经过的步数为环的长度-1。

代码:

#include <bits/stdc++.h>
#define mp make_pair
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
typedef long long LL;
const int maxn = 3e5 + 10;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
using namespace std;
int u, v, n, m, path[maxn], vis[maxn];
LL ans = 1, cnt, mod = 998244353, sum = 0;
vector<int> g[maxn];
LL qpow(LL x) {LL res = 1, temp = 2;while (x) {if (x & 1) {res = (res * temp) % mod;}temp = (temp * temp) % mod;x >>= 1;}return res % mod;
}
void dfs(int now, int pre) {vis[now] = 1;for (int i = 0; i < g[now].size(); ++i) {int to = g[now][i];if (to == pre)continue;if (vis[to] == 0) {path[to] = now;dfs(to, now);}else if (vis[to] == 2) {continue;}else {int temp = now;cnt = 1;while (temp != to) {++cnt;temp = path[temp];}sum += cnt;ans = (ans * (qpow(cnt) - 1)) % mod;}}vis[now] = 2;
}
int main() {scanf("%d %d", &n, &m);for (int i = 1; i <= m; ++i) {scanf("%d %d", &u, &v);g[u].push_back(v);g[v].push_back(u);}for (int i = 1; i <= n; ++i) {if (vis[i] == 0) {dfs(i, 0);}}printf("%lld\n", qpow(m - sum) * ans % mod);}

View Code

转载于:https://www.cnblogs.com/smallhester/p/11606819.html

2019 CCPC 秦皇岛F Forest Program(dfs)相关推荐

  1. 2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program

    2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program 题目链接 The kingdom of Z ...

  2. HDU6736 F.Forest Program(dfs找环)

    F.Forest Program 千摆渡题解 找环可以使用dfs一遍求出. 方法为:vis数组设置为三种状态,0表示未被访问过.1表示正在被访问,即边指向的结点是当前结点在dfs树上的祖先节点.2表示 ...

  3. Forest Program dfs+tanjar仙人掌

    题目链接 CCPC2019 F题. 题意:给一颗仙人掌树,让你求每一个小环的边的个数,用快速幂即可求解. 思路:第一反应是tanjar乱搞,把每个环上的点取出来,类似于缩点的方法.但是忽然感觉dfs能 ...

  4. 2019 CCPC 秦皇岛: MUV LUV EXTRA

    MUV LUV EXTRA (本篇主要内容,kmp求最短循环节) 题目传送门: MUV LUV EXTRA 题意: 给你一个字符串和两个整数a和b.在小数点后,找到一个循环节 l,循环长度为p.求 a ...

  5. 2019 CCPC秦皇岛 K.MUV LUV UNLIMITED(博弈)

    2019CCPC秦皇岛K 题意: 两个人玩游戏, 有一棵有根树,每次只能拿叶子节点若干个(不能不拿),问最后谁会赢 思路: 先说结论,数每个叶子节点对应上去的那条链(直到他的父亲除自己外有另外的儿子结 ...

  6. 【HDU6742 2019 CCPC 秦皇岛 】MUV LUV ALTERNATIVE 曼哈顿剧院 两出口观众逃生最短时间

    应岛娘邀请,自费机票回国打比赛. 队名--友谊是魔法.最终榜单如下--https://ccpc.io/post/187 这题是场上的L题. 一年多不写题也不想题情况下遇上了这场比赛的L题.是个贪心题, ...

  7. 2019 CCPC 秦皇岛 MUV LUV EXTRA kmp

    传送门 枚举循环节已出现的长度 p,最优的循环节就是最后 p 个字 符构成的字符串的最短周期. 考虑把字符串倒过来,使用 kmp 可以求出每个前缀的最短 周期,即求出了原串每个后缀的最短周期. #in ...

  8. 2019 CCPC秦皇岛 J 题 MUV LUV EXTRA【KMP 求最小循环节】

    题意: 原题意是给出一个有理数的前一部分,求这个有理数的无限循环部分是什么.有一个值来评估猜的准确度.转换一下就成了下面的题意: 给出一个字符串s,有某一个子串,设p为该子串在s的某个后缀中的匹配长度 ...

  9. 秦皇岛 2019 CCPC区域赛 部分代码

    Decimal Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Sub ...

最新文章

  1. 山东计算机类好的民办大学,山东四大坑人学校-山东坑人的民办大学(野鸡大学)...
  2. asp.net 一次性提交大量数据,服务器会报错,要在 web.config 中设置一下
  3. 龙岗网络推广解析有关网站SEO排名上去了,但没实际性点击的问题
  4. java中处理字符编码(网页与数据库)(转)
  5. Java基础day5
  6. vue3.x案例 购物车
  7. rm: cannot remove directory `misc': Device or resource busy
  8. ssacanf\Sprintf格式化字符串
  9. DELL服务器R230 RIAD1创建
  10. KMP算法(C++版)
  11. ActiveMQ Windows部署
  12. 软件工程期末考试复习(二)
  13. 在你的Android上执行Linux命令
  14. centors7 和 win7 修改开机顺序
  15. Java 学习 day04
  16. Multisim14.0详细安装教程图文
  17. http接口开发几种工具简单介绍
  18. springboot图片验证码
  19. 详解网易有道AI战略,智能硬件、教育、办公三大解决方案
  20. 入手华为云学生机体验

热门文章

  1. JavaScript学习(四十七)—构造方法创建对象的不足
  2. 借条已经收回,他以没收据为由让我继续还款怎样办?
  3. 几个互联网巨头的社区团购还不收手?
  4. 为什么个体户做不大?
  5. 做企业:要么靠规模,要么靠利润
  6. 当一个人把一个行业说得特别容易赚钱的时候
  7. OpenStack 的诞生
  8. 改进后的新String类
  9. Java-占位符的使用
  10. C++STL之fill()函数使用方法