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 = 102000;
const int mod = 1000000007;
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 == 1) return now;
    if(p == 0) return 1;
    ll z = fast_pow(now,p/2); z*=z; z %= mod;
    if(p & 1){z*=now;z%=mod;}
    return z;
}

void read(){
    scanf("%d%d%d%d",&n,&m,&x,&y);
    for(int i=1;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=2;i<=n;i++) inv[i] = fast_pow(in[i],mod-2);
}

void dfs(int now){
    if(arr[now]) return;
    arr[now] = 1;
    for(int i=0;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 = 1;
    for(int i=2;i<=n;i++) ans = (ans*in[i]) % mod;
    if(x == y){printf("%lld\n",ans);return;}
    if(y == 1){printf("%lld\n",ans);return;}
    for(int i=2;i<=n;i++) if(i != y) ans2 = (ans2*in[i]) % mod;
    in[y]++;inv[y] = fast_pow(in[y],mod-2);dist[y] = inv[y];arr[y] = 1;dfs(x);
    ans += ans2; ans %= mod;
    ans -= (ans*dist[x])%mod; ans += mod; ans %= mod;
    printf("%lld\n",ans);
}

int main(){
    read();
    work();
    return 0;
}

原文地址:https://www.cnblogs.com/1-1-1-1/p/8596753.html

时间: 2024-08-06 01:58:31

luogu3244 bzoj4011 HNOI2015 落忆枫音的相关文章

BZOJ4011 [HNOI2015]落忆枫音

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂--我们也不可能再见 到你姐姐吧.」 恒逸给出了一个略微无厘头的回

BZOJ 4011: [HNOI2015]落忆枫音( dp )

DAG上有个环, 先按DAG计数(所有节点入度的乘积), 然后再减去按拓扑序dp求出的不合法方案数(形成环的方案数). -------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long l

【BZOJ 4011】 [HNOI2015]落忆枫音

4011: [HNOI2015]落忆枫音 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 244 Solved: 137 [Submit][Status][Discuss] Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂--我们也不可能再见 到你姐姐吧.」 恒逸给出了一个略微无厘头的回答.枫茜听后笑了笑.

[HNOI2015] 落忆枫音

题目描述 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂......我们也不可能再见到你姐姐吧.」 恒逸给出了一个略微无厘头的回答.枫茜听后笑了笑. 「那你仔细观察过枫叶吗?」 说罢,枫茜伸手,接住了一片飘落的枫叶. 「其实每一片枫叶都是有灵魂的.你看,枫叶上不是有这么多脉络吗?我听说,枫叶上有一些特殊的位置,就和人的穴位一样.脉络都是连接在这些穴位之间的.枫树的灵魂流过每片枫叶

【bzoj4011】落忆枫音

Description 给出一个有n个点和m条边的有向无环图,1号节点入度为0.这个有向无环图存在一个树形子图,是以1号节点为根的包含全部n个点的一棵树.该树形子图可能有多种可能性. 现在向图中加入一条与已有边不同的有向边(连接两个节点但方向不同视为不同的边),这条边可连向自身.原有向无环图添加新边后得到的新图可能会出现环. 求新图中以1为根的树形子图的方案数.(对1000000007取模) Solution 我们可以得到,有向无环图中树形子图的方案数为2号节点到n号节点的入度的乘积. 设新边为

BZOJ 4011 HNOI2015 落忆枫音 拓扑序DP

题目大意:给定一张有向无环图,现在要求加入一条边,求加入后以1为根的树形图个数 首先不考虑加入的这条边,那么这个图是一个DAG 由朱刘算法的推论可知,如果除根节点外每个点都选择一条入边,由于没有环,因此一定会形成一个树形图 因此答案就是∏ni=2degreei 其中degreei表示第i个点的入度 现在加入这条边之后,我们仍然可以套用这个公式,但是这样就会有一些不合法的方案被统计进来,我们需要把这些不合法的方案减掉 一个方案如果不合法,那么一定会形成一个环,而环一定包含新加入的那条边 因此我们减

BZOJ 4011 HNOI2015 落忆枫音 DAG上的dp(实际上重点在于分析)

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4011 题意概述:给出一张N点的DAG(连通),点1的入度为0.现在加一条原图没有的边,问有多少种方案可使这张图变成一棵以1为根的有向树(即每个点的父亲指向自己). N<=100000,M<=min(200000,N(N-1)/2). 实际上这个题主要在分析(感觉终于开始自己做出省选题了). 先看没有加边的情况,yy一下你发现这种情况的答案就是所有rd(入度)不为0的点rd相乘.道理是只

【BZOJ】【4011】【HNOI2015】落忆枫音

拓扑排序+DP 题解:http://blog.csdn.net/PoPoQQQ/article/details/45194103 http://www.cnblogs.com/mmlz/p/4448742.html 通过转化……路径外的$degree_i$的乘积转化成所有点的degree之积除以路径内的,所以用到逆元…… PoPoQQQ的线性筛逆元好神奇啊……>_< OrzOrz 1 /******************************************************

【bzoj4011 hnoi2015】落忆枫音

题目描述 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂......我们也不可能再见到你姐姐吧.」 恒逸给出了一个略微无厘头的回答.枫茜听后笑了笑. 「那你仔细观察过枫叶吗?」 说罢,枫茜伸手,接住了一片飘落的枫叶. 「其实每一片枫叶都是有灵魂的.你看,枫叶上不是有这么多脉络吗?我听说,枫叶上有一些特殊的位置,就和人的穴位一样.脉络都是连接在这些穴位之间的.枫树的灵魂流过每片枫叶