2018-8-10考试 T3. 朝暮(akekure)
题目大意:有$n$个点和$m$条边的图($n - 1 \leq m \leq n + 5$),每个点要么黑要么白,两个黑点不可以相邻,问方案数
题解:可以发现当图为一棵树的时候只需要一个树形$DP$
$$令f_{i,j}表示在第i个点,它的状态为j(1为黑,0为白)$$
$$f_{i,0}=\prod\limits_{j为i的儿子}(f_{j,0}+f_{j,1})(因为它的儿子没有限制,可以黑可以白)$$
$$f_{i,0}=\prod\limits_{j为i的儿子}f_{j,0}(它的儿子有限制,必须为白)$$
再来考虑不为树的情况,可以发现这个图最多有$6$条返祖边,我们可以暴力枚举这几条边两端的情况,这样复杂度是$O(4^{m-n+1}\times n)$。
明显是不行的,可以发现两端为黑是一定不可能的,这样复杂度成为了$O(3^{m-n+1}\times n)$。
看来可以的,但是遍历图的常数太大,还是过不了,考虑优化。
发现其实对于一条边,可以变成只处理其中的一个点,这样就只有两种状态了,一种是这个点白点,另一个点就无限制;另一种是这个点为黑点,另一个点就是白点,复杂度就成了$O(2^{m-n+1}\times n)$,轻松$AC$
卡点:1.考试时复杂度为$O(3^{m-n+1}\times n)$
C++ Code:
#include <cstdio>
#include <cctype>
#define maxn 100100
using namespace std;
const long long mod = 1000000007;
const long long half = 500000004;
int n, m;
long long ans;
int fa[maxn], oth[50], tot;
int f[maxn][2]; int head[maxn], cnt;
struct Edge {
int from, to, nxt;
bool can;
} e[(maxn + 10) << 1];
void add(int a, int b) {
e[++cnt] = (Edge) {a, b, head[a], true}; head[a] = cnt;
} char *ch, op[1 << 25 | 100];
inline void read(int &x) {
x = 0;
while (isspace(*ch)) ch++;
while (isdigit(*ch)) x = x * 10 + (*ch++ & 15);
} bool vis[maxn];
void dfs(int rt) {
vis[rt] = true;
int v;
for (register int i = head[rt]; i; i = e[i].nxt) {
v = e[i].to;
if (v != fa[rt]) {
if (!vis[v]) {
fa[v] = rt;
dfs(v);
} else {
e[i].can = false;
if (v > rt) oth[++tot] = i;
}
}
}
}
bool ispoint[maxn], mus[maxn];
inline void real(int rt) {
int v;
int &_0 = f[rt][0], &_1 = f[rt][1];
_0 = _1 = 1;
if (ispoint[rt]) f[rt][mus[rt] ^ 1] = 0;
for (int i = head[rt]; i; i = e[i].nxt) {
if (e[i].can) {
v = e[i].to;
if (v != fa[rt]) {
real(v);
_0 = (1ll * _0 * (f[v][1] + f[v][0])) % mod;
_1 = (1ll * _1 * f[v][0]) % mod;
}
}
}
}
void run(int x) {
if (x > tot) {
real(1);
ans = (ans + f[1][1] + f[1][0]) % mod;
return ;
}
int u = e[oth[x]].from, v = e[oth[x]].to;
bool &iu = ispoint[u], &iv = ispoint[v], &mu = mus[u], &mv = mus[v];
if (iu && iv) {
run(x + 1);
return ;
}
if (iu || iv) {
if (iv) u ^= v ^= u ^= v;
if (mus[u]) {
ispoint[v] = true;
mus[v] = false;
run(x + 1);
ispoint[v] = false;
} else {
run(x + 1);
}
return ;
}
iu = true;
mu = false;
run(x + 1);
iu = false;
iu = iv = true;
mu = true;
mv = false;
run(x + 1);
iv = iu = false;
}
int main() {
fread(ch = op, 1, 1 << 25, stdin);
read(n), read(m);
for (register int i = 0; i < m; i++) {
int a, b;
read(a), read(b);
add(a, b);
add(b, a);
}
dfs(1);
run(1);
printf("%lld\n", ans);
return 0;
}
2018-8-10考试 T3. 朝暮(akekure)的更多相关文章
- 申请Office 365一年免费的开发者账号攻略(2018年10月份版本)
要进行Office 365开发,当然需要有完整的Office 365环境才可以.为了便于广大开发人员快速地启动这项工作,微软官方给所有开发人员提供了免费的一年开发者账号 那么如何申请Office ...
- IntelliJ IDEA 最新激活码(截止到2018年10月14日)
IntelliJ IDEA 注册码: EB101IWSWD-eyJsaWNlbnNlSWQiOiJFQjEwMUlXU1dEIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYX ...
- 新手C#SQL Server使用记录2018.08.10
主键(PrimaryKey):主键就是每个数据行(记录)的唯一标识,不会有重复值的列(字段)才能当做主键.一个表可以没有主键,但是这样会很难处理表,因此一般情况表都要设置主键. 主键有两张选用策略,分 ...
- 01 mybatis框架整体概况(2018.7.10)-
01 mybatis框架整体概况(2018.7.10)- F:\廖雪峰 JavaEE 企业级分布式高级架构师课程\廖雪峰JavaEE一期\第一课(2018.7.10) maven用的是3.39的版本 ...
- 北京化工大学2018年10月程序设计竞赛部分题解(A,C,E,H)
目录 北京化工大学2018年10月程序设计竞赛部分题解(A,C,E,H) 竞赛事件相关 竞赛链接 竞赛题目 总结 北京化工大学2018年10月程序设计竞赛部分题解(A,C,E,H) 竞赛事件相关 竞赛 ...
- 富士康的盈利秒杀99%的A股公司:3星|《三联生活周刊》2018年10期
三联生活周刊·最美的数学:天才为何成群到来(2018年10期) 本期专题是数学和成都,我都跳过去没看.其他内容也还有点意思. 总体评价3星. 以下是本期一些内容的摘抄,#号后面是kindle电子版中的 ...
- Burn Down Chart(2018.6.4~2018.6.10)
Burn Down Chart (2018.6.4~2018.6.10) 娄雨禛[前端部分] 曾子轩[后端部分+燃尽图] 前端 1. 娄雨禛+李鑫 1)在总工程中完成跳转,实现图片显示,并发布到Git ...
- Java分布式互联网架构/微服务/高性能/springboot/springcloud 2018年10月17日直播内容
2018年10月17日直播内容 大规模并发必备的消息中间件技术ActiveMq 网盘链接: https://pan.baidu.com/s/1GlxsZ2JnrvX- YN16-S7lQw 提取码: ...
- 题解 2020.10.24 考试 T3 数列
题目传送门 题目大意 给出一个数 \(n\),你要构造一个数列,满足里面每个数都是 \(n\) 的因子,且每一个数与前面不互质的个数不超过 \(1\).问有多少种合法方案. 保证 \(n\) 的不同质 ...
随机推荐
- html5 获取和设置data-*属性值的四种方法讲解
1.获取id的对象 2.需要获取的就是data-id 和 dtat-vice-id的值 一:getAttribute()方法 const getId = document.getElementById ...
- 中国农产品信息网站scrapy-redis分布式爬取数据
---恢复内容开始--- 基于scrapy_redis和mongodb的分布式爬虫 项目需求: 1:自动抓取每一个农产品的详细数据 2:对抓取的数据进行存储 第一步: 创建scrapy项目 创建爬虫文 ...
- Java学习笔记十四:如何定义Java中的类以及使用对象的属性
如何定义Java中的类以及使用对象的属性 一:类的重要性: 所有Java程序都以类class为组织单元: 二:什么是类: 类是模子,确定对象将会拥有的特征(属性)和行为(方法): 三:类的组成: 属性 ...
- YSZOJ:#247. [福利]可持久化线段树 (最适合可持久化线段树入门)
题目链接:https://syzoj.com/problem/247 解题心得: 可持久化线段树其实就是一个线段树功能的加强版,加强在哪里呢?那就是如果一颗普通的线段树多次修改之后还能知道最开始的线段 ...
- c/c++ 数组传参
在c/c++中,在进行数组传参时,数组的元素个数默认是不作为实参传入调用函数,也就是说c/c++ 不允许向函数传递一个完整的数组作为参数 实例: 1.形式参数是一个指针,实参包括数组长度: 1 voi ...
- HashMap源码注释翻译
HashMap.java(JDK1.8) 如有错误翻译的地方,欢迎评论指出. 介绍:对于HashMap及其子类而言,它们采用Hash算法来决定集合中元素的存储位置.当系统开始初始化HashMap时,系 ...
- 转MySQL详解--索引
写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...
- 【APUE】Chapter10 Signals
Signal主要分两大部分: A. 什么是Signal,有哪些Signal,都是干什么使的. B. 列举了非常多不正确(不可靠)的处理Signal的方式,以及怎么样设计来避免这些错误出现. 10.2 ...
- OpenCV入门:(六:基础画图函数)
有时程序中需要画一些基础的图形,例如直线,矩形,椭圆以及多边形.OpenCV中当然有此类函数. 1.函数介绍 直线line: , , ) img – 图像 pt1 – 直线起点 pt2 – 直线终点 ...
- 初探Qt Opengl【1】
最近一直在学习Qt的opengl绘图,看到好多资源都是关于以前的旧版本的, 我将我这几天学的的部分关于opengl的做个总结,也希望对需要学习的人有一定的帮助 在我的学习中,我主要用到一下三个方法 # ...