2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)G.希望(Floyd)

题意可知两棵树之间的所有n!种连边方式均会被遍历到,求期望值。

题意说A与B树之间连接成长为m的环,设由A中某条长为aa的链,与B中某条长为bb的链首尾相接而成,由于两棵树之间连接还需要两条边,所以aa+bb+2==m。设A中所有距离为aa的边有a[aa]个,B中距离为bb的边有b[bb]个。

当a树中aa条边与b树中bb条边连接成边时,此时其他点的连接方式共(n-2)!种。

因此,树A中长为aa的所有情况与树B中长为bb所有情况进行相乘,对答案的贡献为2*(n-2)!*a[aa]b[bb]。由1到m-3枚举所有合法aa+bb=m-2,累加即得到总方案数。由于最终答案会除以n!,因此可以将阶乘项消去,得到方案数最终除以n(n-1)即可。

其中,计算边长的部分由Floyd算法算出。

#include
#include
#include
#include
using namespace std;
const int INF = 0x3f3f3f3f;
int A[305][305];
int B[305][305];
vector<long long>a(500, 0);
vector<long long>b(500, 0);

int main()
{
     
	// 初始化A图和B图
	memset(A, INF, sizeof(A));
	memset(B, INF, sizeof(B));
	double n, m;
	cin >> n >> m;
	// 由于是无向图所以a->b和b->a都需要算权重为1
	// 输入A图
	for (int i = 0; i < n - 1; i++)
	{
     
		int a, b;
		cin >> a >> b;
		A[a][b] = 1;
		A[b][a] = 1;
	}
	// 输入B图
	for (int i = 0; i < n - 1; i++)
	{
     
		int a, b;
		cin >> a >> b;
		B[a][b] = 1;
		B[b][a] = 1;
	}
	// Floyd跑一遍A图
	for (int k = 1; k <= n; k++)
	{
     
		for (int i = 1; i <= n; i++)
		{
     
			for (int j = 1; j <= n; j++)
			{
     
				A[i][j] = min(A[i][j], A[i][k] + A[k][j]);
			}
		}
	}
	// 记录一下A图中各个长度的边的个数,为防止一条边被计算两次,所以限制只能低序号到高序号的边计数
	for (int i = 1; i <= n; i++)
	{
     
		for (int j = i + 1; j <= n; j++)
		{
     
			if (A[i][j] != INF)
			{
     
				a[A[i][j]]++;
			}
		}
	}
	// Floyd跑一遍B图
	for (int k = 1; k <= n; k++)
	{
     
		for (int i = 1; i <= n; i++)
		{
     
			for (int j = 1; j <= n; j++)
			{
     
				B[i][j] = min(B[i][j], B[i][k] + B[k][j]);
			}
		}
	}
	// 记录一下B图中各个长度的边的个数,为防止一条边被计算两次,所以限制只能低序号到高序号的边计数
	for (int i = 1; i <= n; i++)
	{
     
		for (int j = i + 1; j <= n; j++)
		{
     
			if (B[i][j] != INF)
			{
     
				b[B[i][j]]++;
			}
		}
	}
	// 计算期望
	double res = 0;
	// aa代表从a树中取的边数,由于a树中的边数+b树中的边数+2=m,所以b树中的边数为m-2-aa
	// 乘2是因为两条边可以都从a树低序号指向b树高序号,也可以一条边由a树低序号指向b树高序号一条由a树高序号指向b树低序号
	for (int aa = 1; aa < m - 2; aa++)
	{
     
		int bb = m - 2 - aa;
		res += (double)(a[aa] * b[bb] * 2)/(n * (n - 1));
	}
	printf("%.4lf", res );
	return 0;
}

你可能感兴趣的:(文章,算法)