P4208 [JSOI2008]最小生成树计数

Posted Sunny_r

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4208 [JSOI2008]最小生成树计数相关的知识,希望对你有一定的参考价值。

题目描述

现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对(31011)的模就可以了。

题解

容易想到对于边权相同的那些边,选出来的边数是一定的,所以最终答案其实就是各个边权相同的部分的方案数的乘积,用并查集维护(dfs)即可,注意:由于有撤销操作,所以不能进行路径压缩。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1005;
const int mod = 31011;
int n, m, fa[N], cnt, tot, sum, ans = 1, now;
struct node{int x, y, z;}a[N];
struct data{int l, r, val;}e[N];
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < ‘0‘ || ch > ‘9‘) {if(ch == ‘-‘) f = -1; ch = getchar();}
	while(ch >= ‘0‘ && ch <= ‘9‘) {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
bool cmp(const node & a, const node & b) {return a.z < b.z;}
int find(int x) {return fa[x] == x ? x : find(fa[x]);}
void dfs(int x, int goal, int num)
{
	if(x == goal + 1) {if(num == now) sum ++; return;}
	int xx = find(a[x].x), yy = find(a[x].y);
	if(xx != yy)
	{
		fa[xx] = yy; dfs(x + 1, goal, num + 1);
		fa[xx] = xx; fa[yy] = yy;
	}
	dfs(x + 1, goal, num);
}
int main()
{
//	freopen("a.in", "r", stdin);
//	freopen("a.out", "w", stdout);
	n = read(); m = read();
	for(int i = 1; i <= n; i ++) fa[i] = i;
	for(int i = 1; i <= m; i ++) a[i].x = read(), a[i].y = read(), a[i].z = read();
	sort(a + 1, a + m + 1, cmp);
	for(int i = 1; i <= m; i ++)
	{
		if(a[i].z != a[i - 1].z) cnt ++, e[cnt].l = i, e[cnt - 1].r = i - 1;
		int x = find(a[i].x), y = find(a[i].y);
		if(x != y) {fa[x] = y; tot ++; e[cnt].val ++;}
	}
	e[cnt].r = m; if(tot != n - 1) {printf("0
"); return 0;}
	for(int i = 1; i <= n; i ++) fa[i] = i;
	for(int i = 1; i <= cnt; i ++)
	{
		sum = 0; now = e[i].val; dfs(e[i].l, e[i].r, 0); ans = (ans * sum) % mod;
		for(int j = e[i].l; j <= e[i].r; j ++)
		{
			int x = find(a[j].x), y = find(a[j].y);
			if(x != y) fa[x] = y;
		}
	}
	printf("%d
", ans);
	return 0;
}

以上是关于P4208 [JSOI2008]最小生成树计数的主要内容,如果未能解决你的问题,请参考以下文章

P4208 [JSOI2008]最小生成树计数

P4208 [JSOI2008]最小生成树计数

P4208 [JSOI2008]最小生成树计数

P4208 [JSOI2008]最小生成树计数

luogu4208

BZOJ 1016: [JSOI2008]最小生成树计数