Matrix_Tree定理 高斯消元做法

#include<iostream>  
#include<cmath>  
#include<cstdio>  
#include<cstring>  
using namespace std;
typedef long long ll; 
const int mod=998244353;
int a[2002][2002];  
int b[2002][2002];    
int n,m;
inline int fp(int a,int b){
	int ret=1;
	while(b){
		if(b&1)ret=1ll*ret*a%mod;
		a=1ll*a*a%mod;
		b>>=1;
	}
	return ret;
}  
inline int gs(){    
    register int ret=1,t,sign=0;
    for(register int i=1;i<n;++i)  
        for(register int j=1;j<n;++j)  
			b[i][j]=(mod+a[i][j])%mod;  
    for(register int i=1;i<n;++i){  
        if(!b[i][i]){
			register int j;  
            for(j=i+1;j<n;++j)  
                if(b[j][i])  
                    break;
			if(j==n)  
                return 0;
            for(register int k=i;k<n;++k)  
                t=b[i][k],b[i][k]=b[j][k],b[j][k]=t;  
            ++sign;  
        }
        ret=1ll*ret*b[i][i]%mod;  
        for(register int k=i+1;k<n;++k)  
            b[i][k]=1ll*b[i][k]*fp(b[i][i],mod-2)%mod;  
        for(register int j=i+1;j<n;++j)  
            for(register int k=i+1;k<n;++k)  
                b[j][k]=(b[j][k]-1ll*b[j][i]*b[i][k]%mod+mod)%mod;  
    }
    if(sign&1)
		ret=-ret;  
    return (ret+mod)%mod;  
}  
inline void build(){
	int x,y;
    while(m--){
        scanf("%d%d", &x, &y);
        --a[x][y];--a[y][x];
		++a[x][x];++a[y][y];  
    }  
}  
int main() {  
	scanf("%d%d", &n, &m);    
	build();    
    printf("%d\n",gs());    
    return 0;  
} 

  

posted @ 2018-01-05 22:30  Stump  阅读(145)  评论(0编辑  收藏  举报