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

简介: 2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)G.希望(组合数学 bfs)

题意:

20200401134307494.png

思路

考虑m很小,分类讨论就行。

如果环是m的话,那么中间两条边,也就是说在A , B树的环的长度为m − 2

以m = = 5为例,在A , B树的环长度为3,可以是A 2 + B 1和A 1 + B 2。

也就是说从A树里选择长度为2的路径,从B树里选择长度为1的路径。

所以记g a i表示A树里长度为i的路径种数,g b i表示B树里长度为i的路径长度。这两个数组可以通过b fs求出来。

从A的路径端点向B的路径端点连边,方案数为2

对于A树,两个点已经确定了,其余点任意连边的方案数为( n − 2 ) !

总的概率为1 n !约分后就变成了2 ∗ ( g a 1 ∗ g b 2 + g a 2 ∗ g b 1 ) / ( n ∗ ( n − 1 ) )

其他也同理。

代码

#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll>PLL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define I_int ll
#define x first
#define y second
inline ll read()
{
    ll 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*10+ch-'0';ch=getchar();}
    return x*f;
}
#define read read()
char F[200];
inline void out(I_int x) {
    if (x == 0) return (void) (putchar('0'));
    I_int tmp = x > 0 ? x : -x;
    if (x < 0) putchar('-');
    int cnt = 0;
    while (tmp > 0) {
        F[cnt++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while (cnt > 0) putchar(F[--cnt]);
    //cout<<" ";
}
ll ksm(ll a,ll b,ll p){ll res=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}return res;}
const int inf=0x3f3f3f3f;
const ll mod=998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn=500,maxm=3e6+7;
const double PI = atan(1.0)*4;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
vector<int>ea[310],eb[310];
ll ga[10],gb[10];
ll dep[310];
void bfs1(int s){
  memset(dep,0x3f,sizeof dep);
  queue<int>q;q.push(s);dep[s]=0;
  while(!q.empty()){
    int t=q.front();q.pop();
    for(int i=0;i<ea[t].size();i++){
      int j=ea[t][i];
      if(dep[j]>dep[t]+1){
        dep[j]=dep[t]+1;
        q.push(j);
      }
    }
  }
}
void bfs2(int s){
  memset(dep,0x3f,sizeof dep);
  queue<int>q;q.push(s);dep[s]=0;
  while(!q.empty()){
    int t=q.front();q.pop();
    for(int i=0;i<eb[t].size();i++){
      int j=eb[t][i];
      if(dep[j]>dep[t]+1){
        dep[j]=dep[t]+1;
        q.push(j);
      }
    }
  }
}
int main(){
  ll n=read,m=read;
  rep(i,1,n-1){
    int u=read,v=read;
    ea[u].push_back(v);
    ea[v].push_back(u);
  }
  rep(i,1,n-1){
    int u=read,v=read;
    eb[u].push_back(v);
    eb[v].push_back(u);
  }
  rep(i,1,n){
    bfs1(i);
    rep(j,1,n){
      if(dep[j]>0&&dep[j]<=m) ga[dep[j]]++;
    }
  }
  rep(i,1,n){
    bfs2(i);
    rep(j,1,n){
      if(dep[j]>0&&dep[j]<=m) gb[dep[j]]++;
    }
  }
  rep(i,0,9){
    ga[i]/=2;gb[i]/=2;
  //  cout<<i<<" "<<ga[i]<<" "<<gb[i]<<"\n";
  }
  double ans;
  if(m==3) ans=0.0000;
  else if(m==4){
    if(n-1<=0){
      ans=0.0000;
    }
    else ans=2.0*(n-1)*(n-1)/(n*(n-1));
  }
  else if(m==5){
    if(n-1<=0){
      ans=0.0000;
    }
    else 
    ans=2.0*(ga[2]*gb[1]+ga[1]*gb[2])/(n*(n-1));
  }
  else if(m==6){
    if(n-1<=0){
      ans=0.0000;
    }
    else 
    ans=2.0*(ga[2]*gb[2]+ga[1]*gb[3]+ga[3]*gb[1])/(n*(n-1));
  }
  else if(m==7){
    if(n-1<=0){
      ans=0.0000;
    }
    else 
    ans=2.0*(ga[1]*gb[4]+ga[2]*gb[3]+ga[3]*gb[2]+ga[4]*gb[1])/(n*(n-1));
  }
  printf("%.4lf\n",ans);
  return 0;
}
/*
5 6
1 2
2 3
3 4
4 5
1 2
2 3
3 4
#2.5
4 5
1 2
2 3
3 4
1 2
2 3
3 4
#2.0000
*/



目录
相关文章
|
12天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
29 2
|
5月前
|
存储 机器学习/深度学习 算法
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
61 3
|
1月前
|
存储 缓存 分布式计算
数据结构与算法学习一:学习前的准备,数据结构的分类,数据结构与算法的关系,实际编程中遇到的问题,几个经典算法问题
这篇文章是关于数据结构与算法的学习指南,涵盖了数据结构的分类、数据结构与算法的关系、实际编程中遇到的问题以及几个经典的算法面试题。
30 0
数据结构与算法学习一:学习前的准备,数据结构的分类,数据结构与算法的关系,实际编程中遇到的问题,几个经典算法问题
|
1月前
|
算法 Python
Python算法编程:冒泡排序、选择排序、快速排序
Python算法编程:冒泡排序、选择排序、快速排序
|
1月前
|
机器学习/深度学习 存储 算法
数据结构与算法——BFS(广度优先搜索)
数据结构与算法——BFS(广度优先搜索)
|
3月前
|
存储 算法
BFS算法的实现
BFS算法的实现
49 1
|
3月前
|
存储 算法 搜索推荐
编程之旅中的算法启示
【8月更文挑战第31天】在编程世界的迷宫里,算法是那把钥匙,它不仅能解锁问题的答案,还能引领我们深入理解计算机科学的灵魂。本文将通过一次个人的技术感悟旅程,探索算法的奥秘,分享如何通过实践和思考来提升编程技能,以及这一过程如何启示我们更深层次地认识技术与生活的交织。
|
4月前
|
存储 算法 搜索推荐
告别低效编程!Python算法设计与分析中,时间复杂度与空间复杂度的智慧抉择!
【7月更文挑战第22天】在编程中,时间复杂度和空间复杂度是评估算法效率的关键。时间复杂度衡量执行时间随数据量增加的趋势,空间复杂度关注算法所需的内存。在实际应用中,开发者需权衡两者,根据场景选择合适算法,如快速排序(平均O(n log n),最坏O(n^2),空间复杂度O(log n)至O(n))适合大规模数据,而归并排序(稳定O(n log n),空间复杂度O(n))在内存受限或稳定性要求高时更有利。通过优化,如改进基准选择或减少复制,可平衡这两者。理解并智慧地选择算法是提升代码效率的关键。
70 1
|
3月前
|
存储 算法
【C算法】编程初学者入门训练140道(1~20)
【C算法】编程初学者入门训练140道(1~20)
|
4月前
|
存储 算法 Python
震撼!Python算法设计与分析,分治法、贪心、动态规划...这些经典算法如何改变你的编程世界!
【7月更文挑战第9天】在Python的算法天地,分治、贪心、动态规划三巨头揭示了解题的智慧。分治如归并排序,将大问题拆解为小部分解决;贪心算法以局部最优求全局,如Prim的最小生成树;动态规划通过存储子问题解避免重复计算,如斐波那契数列。掌握这些,将重塑你的编程思维,点亮技术之路。
73 1