D144 最小生成树 Kruskal 算法 P3037 [USACO11DEC] Simplifying the Farm G

D144 最小生成树 Kruskal 算法 P3037 [USACO11DEC] Simplifying the Farm G_哔哩哔哩_bilibili

 

P3037 [USACO11DEC] Simplifying the Farm G - 洛谷

相同的长度值 $c_i$ 最多出现三次,求最小生成树的总边长度和不同最小生成树的数量。

思路

最小生成树的总边长度可以直接跑 Kruskal,不同最小生成树的数量与 “相同的长度值最多出现三次” 有关

每种边的数量有限,边权排序后,相同的边权会聚到一起,从小到大枚举时分类讨论

如果两条边加入会构成环,那么一定不合法

用 $s_1$ 统计相同权值的边数,用 $s_2$ 统计可以加入生成树的边数,有重边时还会不同,所以开个 $set$ 去重统计相同权值的边数

那么,最小生成树的边权和 $sum+=w_i*s_2$,下面看方案数 $cnt$ 的分讨 

1. 如果 $s_1=2$,$s_2=2$,那么方案数不变

    如果 $s_1=2$,$s_2=1$,说明两条加入会构成环,所以任选一条加入,方案数 $cnt*2$

2. 如果 $s_1=3$,$s_2=3$,那么方案数不变

    如果 $s_1=3$,$s_2=1$,说明任选两条加入都会构成环,所以任选一条加入,方案数 $cnt*3$

     

    如果 $s_1=3$,$s_2=2$,如果 $set$ 存了 $2$ 条,说明有两条是重边,方案数 $cnt*2$

    如果 $s_1=3$,$s_2=2$,如果 $set$ 存了 $3$ 条,说明任选两条加入都行,方案数 $cnt*3$

     

统计时用双指针向右跑,快指针统计 $s_1$,慢指针统计 $s_2$

相关板子:

D08【模板】最小生成树 Kruskal 算法 - 董晓 - 博客园

 

// 最小生成树 Kruskal 算法 O(MlogM)
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5,mod=1e9+7;
int n,m,fa[N];
struct E{int x,y,w;}e[N];
long long sum,cnt=1;

int find(int x){
  return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y){
  fa[find(x)]=find(y);
}
signed 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);
  
  for(int i=1;i<=n;i++)fa[i]=i;
  sort(e+1,e+m+1,[&](E a,E b){return a.w<b.w;});
  
  for(int i=1,j,s1,s2; i<=m;){
    set<pair<int,int> >s;
    j=i,s1=0,s2=0;
    while(j<=m && e[i].w==e[j].w){ //如果边权相同
      int x=find(e[j].x),y=find(e[j].y); 
      if(x>y) swap(x,y); //保证起点小,终点大
      if(x!=y){ //不在一个集合
        s1++;  //累计边权相同的边数
        s.insert({x,y}); //set去重
      }
      j++; //快指针j右移
    }
    while(i<j){
      if(find(e[i].x)!=find(e[i].y)){
        merge(e[i].x,e[i].y); //加入生成树
        s2++; //累计可以加入生成树的边数
      }
      i++; //慢指针i右移
    }
    
    (sum+=e[i-1].w*s2)%=mod; //累加最小生成树的边权
    if(s1==2&&s2==1) cnt=(cnt*2)%mod;
    if(s1==3){
      if(s2==1) cnt=(cnt*3)%mod;
      if(s2==2) cnt=(cnt*s.size())%mod;
    } //累乘最小生成树的方案数
  }
  printf("%d %d\n",sum,cnt);
}

 

posted @ 2026-04-28 08:25  董晓  阅读(77)  评论(0)    收藏  举报