一本通1492:最小生成树计数

本文介绍了如何使用C++编程语言,结合并查集和深度优先搜索(DFS)算法,解决网络流问题中的路径计数问题。通过构造并查集和维护拓扑排序,计算满足特定条件的路径数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<bits/stdc++.h>
using namespace std;
const int N = 1100,M = 1e3+7,mod = 31011;
int n,m,tot,cnt;
int ans,sum;
int l[N],r[N],va[N],pre[N];
struct E{
	int from,to,w;
	bool operator < (const E &b) const{
		return w < b.w;
	} 
}e[M];
int find(int x){
	return x==pre[x] ? x: find(pre[x]);
}
void read(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].w);
} 
void dfs(int x,int now,int k){
	if(now == r[x]+1){
		if(k == va[x]) sum++;
		return;
	}
	int fx = find(e[now].from),fy = find(e[now].to);
	if(fx != fy){
		pre[fx] = fy;
		dfs(x,now+1,k+1);
		pre[fx] = fx,pre[fy] = fy;
	}
	dfs(x,now+1,k);
}
void solve(){
	sort(e+1,e+m+1);
	for(int i=0;i<=110;i++) pre[i] = i;
	for(int i=1;i <= m;i++){
		if(e[i].w != e[i-1].w) cnt++,l[cnt]=i,r[cnt-1]=i-1;
		int fx = find(e[i].from),fy = find(e[i].to);
		if(fx != fy){
			pre[fx] = fy;
			va[cnt]++; tot++;
		}
	}
	if(tot != n-1){
		printf("0");return;
	}
	r[cnt] = m;
	for(int i=0;i<=110;i++) pre[i] = i;
	ans = 1;
	for(int i=1;i <= cnt; i++){
		sum = 0;
		dfs(i,l[i],0);
		ans = (ans*sum) % mod;
		for(int j=l[i];j<=r[i];j++){
			int fx = find(e[j].from),fy = find(e[j].to);
			if(fx != fy) pre[fx] = fy;
		}
	}
	printf("%d",ans);
}
int main(){
	read();
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值