Matrix-Tree 定理求最小生成树计数10pts求助
查看原帖
Matrix-Tree 定理求最小生成树计数10pts求助
310773
PCCP楼主2023/8/19 16:23

RT,只过了样例和第一个点。

我把每一个点都和一个虚拟源点相连,防止爆0出来,结果还是爆0了(

求各位巨佬帮蒟蒻看看哪里有问题(

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<set>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=110;
const int M=1e3+10;
const int mod=31011;
int n,m,fa[N],deg[N],blocnt;
bool st[N][N];
long long res=1;
struct edge{
	int x,y,w;
}e[M];
bool cmp(edge a,edge b){
	return a.w<b.w;
}
struct matrix{
	int n;
	int a[N][N];
}lap;
int Gauss(){
	int ans=1;
	lap.n--;
	for(int i=1;i<=lap.n;++i) {
		for(int k=i+1;k<=lap.n;++k) {
			while(lap.a[k][i]) {
				int d=lap.a[i][i]/lap.a[k][i];
				for(int j=i;j<=n;++j){
					lap.a[i][j]=(lap.a[i][j]-1LL*d*lap.a[k][j]%mod+mod)%mod;
				}
				std::swap(lap.a[i],lap.a[k]);
				ans=-ans;
			}
		}
		ans=1LL*ans*lap.a[i][i]%mod;
		ans=(ans+mod)%mod;
	}
	return ans;
}
set<int> q;
int find(int x){
	if(fa[x]==x){
		return x;
	}
	return fa[x]=find(fa[x]);
}
void unify(int x,int y){
	fa[find(y)]=find(x);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
	}
	sort(e+1,e+m+1,cmp);
	int ceiling=0;
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	blocnt=n;
//	cout<<"???????????"<<endl;
	for(int i=1;i<=m;i++){
		if(find(e[i].x)!=find(e[i].y)){
			blocnt--;
			unify(find(e[i].x),find(e[i].y));
		}
		if(blocnt==1&&!ceiling){
			ceiling=e[i].w;
		}
	}
	for(int i=1;i<=m;i++){
		if(e[i].w>ceiling){
			continue;
		}
		for(i;i;i++){
			deg[e[i].x]++,deg[e[i].y]++;
			q.insert(e[i].x),q.insert(e[i].y);
			st[e[i].x][e[i].y]=st[e[i].x][e[i].y]=true;
			if(e[i].w!=e[i+1].w){
				break;
			}
		}
		set<int>::iterator it,th;
		int cnt=0;
		lap.n=q.size();
		for(it=q.begin();it!=q.end();it++){
			++cnt;
			lap.a[cnt][cnt]=deg[*it];
			lap.a[lap.n+1][cnt]=lap.a[cnt][lap.n+1]=-1;
			th=it;
			for(int num=cnt;th!=q.end();th++,num++){
				if(st[*it][*th]==true&&*it!=*th){
					lap.a[cnt][num]=lap.a[num][cnt]=-1;
				}
			}
		}
//		for(int j=1;j<=cnt;j++){
//			for(int k=1;k<=cnt;k++){
//				cout<<lap.a[j][k]<<" ";
//			}
//			cout<<endl;
//		}
		lap.a[lap.n+1][lap.n+1]=lap.n;
		lap.n++;
		res*=Gauss();
		res%=mod;
		for(int j=1;j<=lap.n;j++){
			for(int k=1;k<=lap.n;k++){
				lap.a[j][k]=0;
			}
		}
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
				st[j][k]=0;
			}
		}
		for(it=q.begin();it!=q.end();it++){
			deg[*it]=0;
		}
		q.clear();
	}
	printf("%lld\n",res);
}
2023/8/19 16:23
加载中...