zoukankan      html  css  js  c++  java
  • 【HNOI2015】落忆枫音

    题面

    题解

    求一个有特殊性质的有向图的生成树的个数。

    首先,有向图的生成树的个数可以用矩阵树定理,能够得到(40)分。

    但是如果它是一个(mathrm{DAG})就很好做,枚举每一个点的父亲,答案就是(prod d[i])(d)是每个点的入度

    发现加了一条边之后只会形成一个环,设环上的点为(a_1, a_2, cdots, a_k),那么形成的不合法的生成树有(frac{prod_i d[i]}{prod_{i = 1} ^ k d[a_i]})种。

    于是答案就是(prod_i d[i] - frac{prod_i d[i]}{prod_{i = 1} ^ k d[a_i]})

    代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #define RG register
    #define clear(x, y) memset(x, y, sizeof(x))
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while(ch != '-' && (!isdigit(ch))) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(100010), maxm(200010), Mod(1000000007);
    struct edge { int next, to; } e[maxm];
    int head[maxn], e_num, n, m, vis[maxn], deg[maxn];
    int sx, sy, ans = 1, dmul = 1, f[maxn];
    inline void add_edge(int from, int to)
    {
    	e[++e_num] = (edge) {head[from], to};
    	head[from] = e_num;
    }
    
    int fastpow(int x, int y)
    {
    	int ans = 1;
    	for(; y; y >>= 1, x = 1ll * x * x % Mod)
    		if(y & 1) ans = 1ll * ans * x % Mod;
    	return ans;
    }
    
    void dfs(int x)
    {
    	if(vis[x]) return; vis[x] = 1;
    	if(x == sy) return (void) (f[x] = 1ll * dmul
    			* fastpow(deg[x], Mod - 2) % Mod);
    	for(RG int i = head[x]; i; i = e[i].next)
    		dfs(e[i].to), f[x] = (f[x] + f[e[i].to]) % Mod;
    	f[x] = 1ll * f[x] * fastpow(deg[x], Mod - 2) % Mod;
    }
    
    int main()
    {
    	n = read(), m = read(), sx = read(), sy = read();
    	for(RG int i = 1, a, b; i <= m; i++)
    		a = read(), b = read(), add_edge(b, a), ++deg[b];
    	++deg[1];
    	for(RG int i = 1; i <= n; i++)
    	{
    		if(i == sy) ans = 1ll * ans * (deg[i] + 1) % Mod;
    		else ans = 1ll * ans * deg[i] % Mod;
    		dmul = 1ll * dmul * deg[i] % Mod;
    	}
    	dfs(sx); ans = (ans - f[sx] + Mod) % Mod;
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    va_list va_start va_end va_arg 解决变参问题
    标准输出文件
    Qt QDataTime QString 两个类的使用
    联合开发网站
    iOS LLDB调试器和断点调试
    Wireshark 网络抓包工具Wireshark的使用
    linux 操作系统下c语言编程入门
    iOS 应用崩溃日志分析
    iOS sqlite3数据库解析
    iOS 解析手势识别(Gesture Recognizers)
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10412384.html
Copyright © 2011-2022 走看看