[HNOI 2015]落忆枫音
Description
「恒逸,你相信灵魂的存在吗?」
Input
输入文件的第一行包含四个整数 n、m、x和y,依次代表枫叶上的穴位数、脉
Output
输出一行,为添加了从穴位 x连向穴位 y的脉络后,枫叶上以穴位 1 为根的脉
Sample Input
1 2
1 3
2 4
3 2
Sample Output
HINT
对于所有测试数据,1 <= n <= 100000,n - 1 <= m <= min(200000, n(n – 1) / 2),
题解
首先我们简化这个问题,考虑一个$DAG$中树形图的个数。
值得注意的是这里有朱刘算法的一个推广:
如果除根节点外每个点都选择一条入边,由于没有环,因此一定会形成一个树形图。
这里简要证明一下:
首先证明这个图是联通的。
采用反证法,假设图不联通,显然原图存在一个子图满足:子图联通,并且子图中边数$w$>点数$u$。
那么这样这个子图的总入度>总点数。那么一定存在一个点入度>$1$。与题设不符,原命题成立。
下证这个连通图满足树形图的性质。
依旧采用反证法,我们假设选择满足题意的边不能够成树形图。那么存在两条不同的路径$S_1$,$S_2$从根节点$1$到达另外一个节点$v$。
假设子图$g(u',w') ⊂$ 原图$G(u,w)$是满足$S_1,S_2 ⊂ g(u',w')$的极小子图。
既然存在两条不同的路径,显然$u' <= w'$。
又由于除根节点外每个点有且仅有一个入边,显然$w' = u'-1$。矛盾,原命题成立。
由上述结论,显然简化版的问题答案就是:$$ans = \prod_{i=2}^n degree_i(其中degree_i表示节点i的入度)$$
我们再来考虑原问题,现在加上额外的一条边之后,原图可能形成环。再由上面的决策,显然不可行。
我们考虑不合法的情况是什么:显然选边的时候构成环就是不合法的。并且这个环中的一条边肯定是$x \rightarrow y$。
容易得到的结论就是,需要减去的不合法的值就是$$\sum_{S是G中y \rightarrow x的一条路径的点集}\prod_{2\leq j\leq n,j\notin S}degree_j$$
考虑贡献法来计算,用$top-sort-dp$,记$f_i$表示$$\sum_{S是G中y \rightarrow i的一条路径的点集}\prod_{2\leq j\leq n,j\notin S}degree_j$$
$dp$方程就是$$f_i=\frac{\sum_{j\rightarrow i}f_j}{degree_i}$$
初值$$f_y=\frac{\prod_{i=2}^ndegree_i}{degree_y}$$
由于$1$号根节点不选入边,所以$1$号点显然不能构成环。若$y == 1$,显然这条边不可能被选,不用$top-sort-dp$,直接输出原始$ans$即可。
//It is made by Awson on 2017.12.24
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int N = ;
const int M = ;
const int MOD = ; int n, m, x, y, u, v;
struct tt {
int to, next;
}edge[M+];
int path[N+], top;
int ans = , degree[N+], in[N+];
int f[N+];
queue<int>Q; int quick_pow(int a, int b) {
int cnt = ;
while (b) {
if (b&) cnt = (LL)cnt*a%MOD;
a = (LL)a*a%MOD;
b >>= ;
}
return cnt;
}
void topsort() {
f[y] = ans;
for (int i = ; i <= n; i++) if (in[i] == ) Q.push(i);
while (!Q.empty()) {
int u = Q.front(); Q.pop();
f[u] = (LL)f[u]*quick_pow(degree[u], MOD-)%MOD;
for (int i = path[u]; i; i = edge[i].next) {
(f[edge[i].to] += f[u]) %= MOD; in[edge[i].to]--;
if (in[edge[i].to] == ) Q.push(edge[i].to);
}
}
}
void add(int u, int v) {
edge[++top].to = v;
edge[top].next = path[u];
path[u] = top;
}
void work() {
scanf("%d%d%d%d", &n, &m, &x, &y);
degree[y]++;
for (int i = ; i <= m; i++) {
scanf("%d%d", &u, &v);
add(u, v); degree[v]++;
}
for (int i = ; i <= n; i++) ans = (LL)ans*degree[i]%MOD;
for (int i = ; i <= n; i++) in[i] = degree[i]; in[y]--;
if (y != ) topsort();
printf("%d\n", (ans-f[x]+MOD)%MOD);
}
int main() {
work();
return ;
}
[HNOI 2015]落忆枫音的更多相关文章
- 【BZOJ】【4011】【HNOI2015】落忆枫音
拓扑排序+DP 题解:http://blog.csdn.net/PoPoQQQ/article/details/45194103 http://www.cnblogs.com/mmlz/p/44487 ...
- BZOJ 4011: [HNOI2015]落忆枫音( dp )
DAG上有个环, 先按DAG计数(所有节点入度的乘积), 然后再减去按拓扑序dp求出的不合法方案数(形成环的方案数). ---------------------------------------- ...
- bzoj4011[HNOI2015]落忆枫音 dp+容斥(?)
4011: [HNOI2015]落忆枫音 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1125 Solved: 603[Submit][Statu ...
- [HNOI2015]落忆枫音 解题报告
[HNOI2015]落忆枫音 设每个点入度是\(d_i\),如果不加边,答案是 \[ \prod_{i=2}^nd_i \] 意思是我们给每个点选一个父亲 然后我们加了一条边,最后如果还这么统计,那么 ...
- 4011: [HNOI2015]落忆枫音
4011: [HNOI2015]落忆枫音 链接 分析: 原来是一个DAG,考虑如何构造树形图,显然可以给每个点找一个父节点,所以树形图的个数就是$\prod\limits_u deg[u]$. 那么加 ...
- BZOJ 4011 【HNOI2015】 落忆枫音
题目链接:落忆枫音 以下内容参考PoPoQQQ大爷的博客 首先我们先来考虑一下如果没有新加入的那条边,答案怎么算. 由于这是一个\(DAG\),所以我们给每个点随便选择一条入边,最后一定会构成一个树形 ...
- 【BZOJ4011】【HNOI2015】落忆枫音(动态规划)
[BZOJ4011][HNOI2015]落忆枫音(动态规划) 题面 BZOJ 洛谷 Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜 ...
- BZOJ4011: [HNOI2015]落忆枫音
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们 ...
- [HNOI2015]落忆枫音
题目描述 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂......我们也不可能再 ...
随机推荐
- Android中Activity和Service的数据通讯
在Android中,我们通常需要Activity跟Service进行通讯,很多人只知道Activity掉用Service,却不知道Service如何将数据返回给Activity.其实Service返回 ...
- Alpha冲刺第十一天
Alpha冲刺第十一天 站立式会议 项目进展 项目进入尾声,主要测设工作完成过半,项目总结也开始进行. 问题困难 项目的困难现阶段主要是测试过程中存在一些"盲点"很难发现或者发现后 ...
- centos7下搭建sentry错误日志服务器
1. docker 安装(方法一) 1.确保yum packages 是最新的 $ sudo yum update 2.添加yum repo $ sudo tee /etc/yum.repos.d/d ...
- Django 模版语法
一.简介 模版是纯文本文件.它可以产生任何基于文本的的格式(HTML,XML,CSV等等). 模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签. {% extends "base ...
- Hibernate之深入持久化对象
Hibernate是一个彻底的O/R Mapping 框架.之所以说彻底,是因为相对于其他的 框架 ,如Spring JDBC,iBatis 需要手动的管理SQL语句,Hibernate采用了完全 面 ...
- Entity Framework Core Code First
参考地址:https://docs.microsoft.com/zh-cn/ef/core/get-started/aspnetcore/new-db
- Angular开发实践(八): 使用ng-content进行组件内容投射
在Angular中,组件属于特殊的指令,它的特殊之处在于它有自己的模板(html)和样式(css).因此使用组件可以使我们的代码具有强解耦.可复用.易扩展等特性.通常的组件定义如下: demo.com ...
- JavaScript查找数组中最大的值
// 查找一个数组中最大的数 // 定义一个方法 searchMax function searchMax(arr) { // 声明一个变量MaxNumber假设为数组中最大的值arr[0]; var ...
- 格式化输出io:format的奇技淫巧
格式化输出io:format是我接触Erlang使用的第一个库函数(io:format("Hello World")),随着学习的深入,它也是我debug优先选择最简单直接的工具. ...
- 帧动画的创建方式 - xml方式
废话不多说,先看东西 创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画: 本文内容主要关注 xml文件 创建帧动画的方式 xml文件 ...