luogu3244 bzoj4011 HNOI2015 落忆枫音
这道题目题面真长,废话一堆。
另外:这大概是我第一道独立做出来的HNOI2011年以后的题目了吧。像我水平这么差的都能做出来,dalao您不妨试一下自己想想?
题目大意:给一个DAG,其中1号点没有入度,现在新加入一条不重复的边,使得它可能有环。求它的生成子图个数,使得子图正好包含N-1条边且1号点与其它的所有点连通。
题目分析:
我们首先要发现这是一个树的结构!有向的树。
分析树的特点,树的父亲只有一个,我们不妨从这里入手。
在这一个生成子图中,谁是谁的父亲?
我们知道1号点一定是root,这是为什么呢?
原因在于一号点没有入度,我们就认为了它是root。
那么假设有一条x->y的路径,那么x就是y的父亲,这样的定义是合理的。
考虑不加边之前的情况,图是一个DAG,我们求它的生成树(姑且这么叫吧)。
根据我们上面的分析,我们猜想:除一号点外所有点的入度乘积为该图的生成树数量。
证明如下:
首先我们考虑这个是怎么来的。每个点选择一个父亲,则根据乘法原理得到上面的猜想。
那么我们的命题是:每个点选一个父亲,则这个方案必定合法。
我们一共对N-1个点选了到fa的边,每次选择都合并了两个点,共合并了N-1次,因此共N个点被合并,又由于不存在环的情况,所以这样的方案是合法的。
考虑多了一条边的情况。那么我们由于已经求得了所有不包含这条边的情况,我们只需要分析多了这条边的情况。
假设这是一条从x到y的边。当这条边必选的时候,y点必定不被考虑。因为它的父亲已经确定。
那么我们对剩下的点重新做一遍乘法,得到了ans2。
考虑答案多了什么。
当选出的边与当前边成环的时候,这个并不是一个生成树,我们没办法解决了吗?当然不是。
我们不妨单独拿出一个环考虑。当形成了这个环的时候,对答案的影响是多少。实际上这不难统计,把剩下的点的入度全部乘起来就是答案。嘿嘿,这不就是总和除以现在的点数吗。
那么我们考虑求y到x的路径的点的入度的逆,DP一发轻松解决。然后乘法分配率证明正确性。
后记:这题我先写了个错的然后发现我想错了,答案小了,调了调变大了,然后又调,结果搜索出了正解233。
代码:
#include<bits/stdc++.h>
using namespace std; typedef long long ll; const int maxn = ;
const int mod = ;
int n,m,x,y;
ll ans,ans2;
int in[maxn],arr[maxn];
ll dist[maxn],inv[maxn];
vector <int> g[maxn];
vector <int> ng[maxn]; ll fast_pow(int now,int p){
if(p == ) return now;
if(p == ) return ;
ll z = fast_pow(now,p/); z*=z; z %= mod;
if(p & ){z*=now;z%=mod;}
return z;
} void read(){
scanf("%d%d%d%d",&n,&m,&x,&y);
for(int i=;i<=m;i++){
int a,b; scanf("%d%d",&a,&b);
g[a].push_back(b);in[b]++;
ng[b].push_back(a);
}
for(int i=;i<=n;i++) inv[i] = fast_pow(in[i],mod-);
} void dfs(int now){
if(arr[now]) return;
arr[now] = ;
for(int i=;i<ng[now].size();i++){
dfs(ng[now][i]);
dist[now] += (dist[ng[now][i]]*inv[now])%mod;
dist[now] %= mod;
}
} void work(){
ans = ans2 = ;
for(int i=;i<=n;i++) ans = (ans*in[i]) % mod;
if(x == y){printf("%lld\n",ans);return;}
if(y == ){printf("%lld\n",ans);return;}
for(int i=;i<=n;i++) if(i != y) ans2 = (ans2*in[i]) % mod;
in[y]++;inv[y] = fast_pow(in[y],mod-);dist[y] = inv[y];arr[y] = ;dfs(x);
ans += ans2; ans %= mod;
ans -= (ans*dist[x])%mod; ans += mod; ans %= mod;
printf("%lld\n",ans);
} int main(){
read();
work();
return ;
}
luogu3244 bzoj4011 HNOI2015 落忆枫音的更多相关文章
- bzoj4011[HNOI2015]落忆枫音 dp+容斥(?)
4011: [HNOI2015]落忆枫音 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1125 Solved: 603[Submit][Statu ...
- BZOJ4011: [HNOI2015]落忆枫音
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们 ...
- BZOJ4011:[HNOI2015]落忆枫音(DP,拓扑排序)
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们也 ...
- BZOJ4011 HNOI2015落忆枫音(动态规划+拓扑排序)
DAG中每个点选一条入边就可以构成一棵有向树,所以如果没有环答案就是∏degreei. 考虑去掉含环的答案.可以看做把环缩点,剩下的点仍然可以任意选入边.于是去除的方案数即为∏degreei/∏deg ...
- [BZOJ4011][HNOI2015] 落忆枫音(学习笔记) - 拓扑+DP
其实就是贴一下防止自己忘了,毕竟看了题解才做出来 Orz PoPoQQQ 原文链接 Description 背景太长了 给定一个DAG,和一对点(x, y), 在DAG中由x到y连一条有向边,求生成树 ...
- BZOJ4011: [HNOI2015]落忆枫音(dp 乘法原理)
题意 题目链接 Sol 非常妙的一道题 设\(inder[i]\)表示\(i\)号节点的度数 首先如果是个DAG的话,可以考虑在每个点的入边中选一条边作为树形图上的边,这样\(ans = \prod_ ...
- [BZOJ4011][HNOI2015]落忆枫音-[dp乱搞+拓扑排序]
Description 传送门 Solution 假如我们的图为DAG图,总方案数ans为每个点的入度In相乘(不算1号点).(等同于在每个点的入边选一条边,最后一定构成一棵树). 然而如果加了边x- ...
- [BZOJ4011][HNOI2015]落忆枫音:拓扑排序+容斥原理
分析 又是一个有故事的题目背景.作为玩过原作的人,看题目背景都快看哭了ToT.强烈安利本境系列,话说SP-time的新作要咕到什么时候啊. 好像扯远了嘛不管了. 一句话题意就是求一个DAG再加上一条有 ...
- bzoj4011 [HNOI2015]落忆枫音 拓扑排序+DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4011 题解 首先考虑如果没有那么一条被新加进来的奇怪的边的做法. 我们只需要给每一个点挑一个父 ...
随机推荐
- 接口-以PHP为例
<?php //使用程序模拟现实情况 //使用规范(方法/属性) interface iUSB { public function start(); public function stop() ...
- string (KMP+期望DP)
Time Limit: 1000 ms Memory Limit: 256 MB Description 给定一个由且仅由字符 'H' , 'T' 构成的字符串$S$. 给定一个最初为空的字符串 ...
- 位置信息类API调用的代码示例合集:中国省市区查询、经纬度地址转换、POI检索等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 中国省市区查询:2017最新中国省市区地址 经纬度地址转换:经纬度 ...
- 吾八哥学Selenium(四):操作下拉框select标签的方法
我们在做web页面自动化测试的时候会经常遇到<select></select>标签的下拉框,那么在Python里如何实现去操作这种控件呢?今天就给大家分享一下这个玩法.为了让大 ...
- Android WebView 保持登录问题
最近有个需求是这样的:在应用中添加一个商城,商城的实现是H5(包括登录).需要将这个H5嵌到原生应用中,并在原生代码中添加支付功能. 接到这个需求的时候,想这不是很简单么,用WebView加载这个页面 ...
- java:产生小数位数为2的随机概率,使得和为1
public static List<InstSec> setDataSec(List<String> instno) { List<InstSec> result ...
- 转:客户端session与服务端session
会话(Session)跟踪是Web程序中常用的技术,用来 跟踪用户的整个会话 .常用的会话跟踪技术是Cookie与Session. Cookie通过在客户端记录信息确定用户身份 , Session通过 ...
- Linux 的进程状态
(1)运行:当一个进程在处理机上运行时,则称该进程处于运行状态.处于此状态的进程的数目小于等于处理器的数目,对于单处理机系统,处于运行状态的进程只有一个.在没有其他进程可以执行时(如所有进程都在阻塞状 ...
- Srtuts2实现登录界面(不连接数据库)
1.设计思路 (1)利用Struts2框架设计出一个登录页面的跳转,当用户名和密码都正确时, 跳到登录成功页面:否则,跳到登录失败页面,并在10秒钟内跳到登录界面: (2)在Action中判断用户名和 ...
- STM32 下的库函数和寄存器操作比较
以 led闪烁中的flashLed函数例子: 库函数操作简单,但是效率不如寄存器操作的高: 寄存器操作很复杂,因为要熟悉上百个寄存器,但是程序效率很高 /**下面是通过直接操作库函数的方式实现IO控制 ...