有向图(树形图)矩阵树定理 学习笔记+洛谷4455 bzoj5297 社交网络 +bzoj4894天赋

如果不知道矩阵树定理,请点击这里
有时我们做题会遇到一些看起来像是要用矩阵树,但是图却是有向图的题目。有人说,对于有向图来说,是没有生成树这个概念的,只有树形图的概念。顾名思义,树形图就是形状是树的有向图。对于这一类题目,分为两种情况,第一种是以 i i i号点为起点的树形图的个数,这种称为外向树;第二种是以 i i i号点为终点的树形图个数,这种称为内向树。
做题时一定认真读题,看明白要求的是哪一种树形图。
对于外向图,它构造出来的矩阵应该是邻接矩阵-出度矩阵,对于内向图,它构造出来的矩阵应该是入度矩阵-邻接矩阵。还有一点与矩阵树定理不太一样,就是题目让我们求第 i i i个点为根的外向树或者内向树个数时,我们只能将构造出的矩阵的第 i i i行和第 i i i列去掉(也就是求 M i i M_{ii} Mii),而不是任意去掉一个 1 1 1 n n n之间的编号相同的行和列。之后用像原来的矩阵树定理一样的方法求解即可。
注意扩欧求逆元容易在取模时出现错误,要特判一下原来的 a i i a_{ii} aii的正负再确定是 ( x + m o d ) % m o d (x+mod)\%mod (x+mod)%mod还是 ( x − m o d ) % m o d (x-mod)\%mod (xmod)%mod
另外就是注意取模!最近做了好多数据很大要多次取模的题,感觉这种卡取模的是真的烦,稍微出一点问题就一分不得,还有时候很长时间找不到错误所在,所以多积累点经验。
来两道例题:(都是裸题)
社交网络:

#include 
using namespace std;

int n,m,ji,mod=10007;
int a[300][300],ans=1;
void exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1;
        y=0;
    }
    else
    {
        exgcd(b,a%b,y,x);
        y-=a/b*x;
    }
}
int ksm(int x,int y,int mod)
{
    int res=1;
    while(y)
    {
        if(y&1)
        res=(res*x)%mod;
        x=(x*x)%mod;
        y>>=1;
    }
    return res;
}
void gauss()
{
    for(int i=2;i<=n;++i)
    {
        int r=i;
        for(int j=i+1;j<=n;++j)
        {
            if(abs(a[r][i])

天赋

#include 
using namespace std;

int n,ji;
char s[400][400];
long long a[320][320],mod=1000000007,ans=1;
long long ksm(long long x,long long y,long long mod)
{
	long long res=1;
	while(y)
	{
		if(y&1)
		res=(res*x)%mod;
		x=(x*x)%mod;
		y>>=1;
	}
	return res;
}
void gauss()
{
	for(int i=2;i<=n;++i)
	{
		int r=i;
		for(int j=i+1;j<=n;++j)
		{
			if(abs(a[r][i])

你可能感兴趣的:(矩阵树定理,学习笔记)