首页 > 其他 > 详细

【LG3244】[HNOI2015]落忆枫音

时间:2019-02-26 11:50:24      阅读:110      评论:0      收藏:0      [点我收藏+]

题面

洛谷

题解

\(20pts\)

枚举每一条边是否在树中即可。

\(10pts\)

我们考虑一张\(DAG\)中构成树的方法数,每个点选一个父亲即可,那么有
\[Ans=\prod_{i=1}^{n} deg_i\]

\(deg_i\)表示点\(i\)的入度,其中\(deg_1=1\)

\(100pts\)

考虑在上面的基础上容斥,

考虑连\(y\rightarrow x\)后出现一个环的情况数,其实就是环上的点固定了父亲,

那么最后答案就是

\[ \prod_{i=1}^{n} deg_i-\frac {\prod_{i=1}^{n} deg_i}{\prod_{j\in loop} deg_j} \]

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring> 
#include <cmath> 
#include <algorithm> 
#include <vector>
#include <queue> 
using namespace std; 
inline int gi() {
    register int data = 0, w = 1;
    register char ch = 0;
    while (!isdigit(ch) && ch != '-') ch = getchar(); 
    if (ch == '-') w = -1, ch = getchar();
    while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
    return w * data; 
} 
const int Mod = 1e9 + 7; 
const int MAX_N = 1e5 + 5, MAX_M = 2e5 + 5; 
int fpow(int x, int y) { 
    int res = 1; 
    while (y) { 
        if (y & 1) res = 1ll * res * x % Mod; 
        x = 1ll * x * x % Mod; 
        y >>= 1; 
    } 
    return res; 
} 
struct Graph { int to, next; } e[MAX_M]; int fir[MAX_N], e_cnt; 
void clearGraph() { memset(fir, -1, sizeof(fir)); e_cnt = 0; } 
void Add_Edge(int u, int v) { e[e_cnt] = (Graph){v, fir[u]}, fir[u] = e_cnt++; } 
int N, M, sx, sy, deg[MAX_N], f[MAX_N]; 
bool vis[MAX_N]; 
void dfs(int x) { 
    if (vis[x]) return ; vis[x] = 1; 
    if (sx == x) return (void)(f[x] = 1ll * fpow(deg[x], Mod - 2)); 
    for (int i = fir[x]; ~i; i = e[i].next) dfs(e[i].to), f[x] = (f[x] + f[e[i].to]) % Mod; 
    f[x] = 1ll * f[x] * fpow(deg[x], Mod - 2) % Mod; 
} 
int main () { 
#ifndef ONLINE_JUDGE 
    freopen("cpp.in", "r", stdin); 
#endif
    clearGraph(); 
    N = gi(), M = gi(), sx = gi(), sy = gi(); 
    for (int u, v, i = 1; i <= M; i++) u = gi(), v = gi(), Add_Edge(u, v), ++deg[v]; 
    ++deg[1];
    int ans = 1, res = 1; 
    for (int i = 1; i <= N; i++) {
        if (i == sy) ans = 1ll * ans * (deg[i] + 1) % Mod;
        else ans = 1ll * ans * deg[i] % Mod;
        res = 1ll * res * deg[i] % Mod; 
    } 
    dfs(sy); ans = (ans - 1ll * res * f[sy] % Mod + Mod) % Mod;
    printf("%d\n", ans); 
    return 0; 
} 

【LG3244】[HNOI2015]落忆枫音

原文:https://www.cnblogs.com/heyujun/p/10435903.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!