Tree Ext
这道题相当于把3道题合了起来。

要求修复的边中恰好有 k 条白边:
五颜六色的幻想乡(附拉格朗日插值法求多项式系数 )
+
bzoj2654 tree(WQS二分 新科技get)

是最小生成树计数而非生成树计数:
BZOJ1016」[JSOI2008] 最小生成树计数

具体可以看看这篇博客,代码中的注释也解释得较清楚

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
const int N=105;
const int M=10005;
int n,m,k,l,r;
int tot,fa[N],pa[N],id[N],num[N];
int x[N],y[N],res[N],coef[N],ans[N];
struct edge{int u,v,w,c;
}e[M];
bool cmp(edge a,edge b){if(a.w==b.w) return a.c<b.c;return a.w<b.w;
}
int find(int u){if(fa[u]==u) return u;return fa[u]=find(fa[u]);
}
int get(int u){if(pa[u]==u) return u;return pa[u]=get(pa[u]);
}
int power(int a,int b){a%=mod;int res=1;while(b){if(b&1) res=res*a%mod;b>>=1;a=a*a%mod;}return res;
}
bool check(int mid){for(int i=1;i<=m;i++)if(!e[i].c) e[i].w+=mid;sort(e+1,e+m+1,cmp);for(int i=1;i<=n;i++) fa[i]=i;int cnt=0;for(int i=1,j=0;j<n-1;i++){int u=find(e[i].u),v=find(e[i].v);if(u!=v){fa[v]=u;j++;if(!e[i].c) cnt++;}}for(int i=1;i<=m;i++)if(!e[i].c) e[i].w-=mid;return cnt>=k;
}
int solve(int l,int r,int x){//矩阵树定理:加入这批边中的部分边,构造已有连通块(看成点)的生成树 static int mat[N][N];memset(mat,0,sizeof(mat));for(int i=l;i<=r;i++){int u=id[e[i].u],v=id[e[i].v];if(u==v) continue;if(e[i].c)mat[u][u]++,mat[v][v]++,mat[u][v]--,mat[v][u]--;else//白边权值为x mat[u][u]+=x,mat[v][v]+=x,mat[u][v]-=x,mat[v][u]-=x;}memcpy(pa,fa,sizeof(fa));for(int i=2;i<=tot;i++){//可能相同边权的边全部连了之后,各个连通块仍不连通,所以要提前在他们之间连一些黑边,不影响答案int u=get(num[i]),v=get(num[i-1]);if(u!=v){pa[v]=u;mat[i][i]++,mat[i-1][i-1]++,mat[i][i-1]--,mat[i-1][i]--;}}for(int i=1;i<=tot;i++)for(int j=1;j<=tot;j++)mat[i][j]=(mat[i][j]%mod+mod)%mod;int res=1;for(int i=1;i<tot;i++){for(int j=i+1;j<tot;j++){if(mat[j][i]){int t=mat[i][i]*power(mat[j][i],mod-2)%mod,tmp;for(int k=i;k<tot;k++){tmp=(mat[i][k]-mat[j][k]*t%mod+mod)%mod;mat[i][k]=mat[j][k];mat[j][k]=tmp;}res=-res;}}}if(res==-1) res+=mod;for(int i=1;i<tot;i++) res=res*mat[i][i]%mod;return res;
}
void lagerange(){static int a[N],b[N],c[N];memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));memset(res,0,sizeof(res));a[0]=1;for(int i=0;i<=tot;i++){b[0]=0;for(int j=1;j<=i+1;j++) b[j]=a[j-1];for(int j=0;j<=i;j++) b[j]=(b[j]-x[i]*a[j]%mod+mod)%mod;for(int j=0;j<=i+1;j++) a[j]=b[j];}for(int i=0;i<=tot;i++){for(int j=0;j<=tot+1;j++) b[j]=a[j];for(int j=tot+1;j>=1;j--){c[j-1]=b[j];b[j-1]=(b[j-1]+1LL*b[j]*x[i]%mod)%mod;}int tmp=1;for(int j=0;j<=tot;j++)if(j!=i) tmp=tmp*(x[i]-x[j]+mod)%mod;tmp=y[i]*power(tmp,mod-2)%mod;for(int j=0;j<=tot;j++){c[j]=c[j]*tmp%mod;res[j]=(res[j]+c[j])%mod;}}
}
signed main(){scanf("%lld%lld%lld",&n,&m,&k);for(int i=1;i<=m;i++)scanf("%lld%lld%lld%lld",&e[i].u,&e[i].v,&e[i].w,&e[i].c);l=-1e9-1,r=1e9+1;//二分找出一个合适的值x,使得所有白边边权均加上x后最小生成树中恰有k条白边 while(l<r){int mid=(l+r+1)/2;if(check(mid)) l=mid;else r=mid-1;}for(int i=1;i<=m;i++)if(!e[i].c) e[i].w+=l;sort(e+1,e+m+1,cmp);for(int i=1;i<=n;i++) fa[i]=i;ans[0]=1;for(l=1;l<=m;l=r+1){r=l;while(r<m&&e[l].w==e[r+1].w) r++;bool flag=false;for(int i=l;i<=r;i++){if(find(e[i].u)!=find(e[i].v)){flag=true;break;}}if(!flag) continue;memset(id,0,sizeof(id));tot=0;//注意fa没有重置,即之前加的边构成的连通块还在 for(int i=l;i<=r;i++){//考虑一批有相同权值的边 int u=find(e[i].u),v=find(e[i].v);e[i].u=u;e[i].v=v;//缩点 if(u!=v){if(!id[u]){id[u]=++tot;num[tot]=u;//这一批边关联的连通块数量+1 }if(!id[v]){id[v]=++tot;num[tot]=v;//这一批边关联的连通块数量+1 }}}for(int i=l;i<=r;i++){int u=find(e[i].u),v=find(e[i].v);if(u!=v) fa[v]=u;}for(int i=0;i<=tot;i++){//把白边边权看成未知数x,基尔霍夫矩阵的行列式为关于x的多项式 //代入不同的x,分别求出对应的y,通过插值求出多项式的各项系数 x[i]=i+1;y[i]=solve(l,r,i+1);}lagerange();memset(coef,0,sizeof(coef));for(int i=0;i<n;i++){//乘法原理,把这一次加边的结果与之前的乘起来 for(int j=0;i+j<n;j++){coef[i+j]+=ans[i]*res[j]%mod;coef[i+j]%=mod;}}memcpy(ans,coef,sizeof(coef));}for(int i=2;i<=n;i++){if(find(i)!=find(1)){puts("0");return 0;}}printf("%lld\n",ans[k]);return 0;
}

[XSY]Tree Ext(矩阵树定理,拉格朗日插值,最小生成树,二分)相关推荐

  1. Wannafly挑战赛23F-计数【原根,矩阵树定理,拉格朗日插值】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/161/F 题目大意 给出nnn个点的一张图,求它的所有生成树中权值和为kkk的倍数的个数.输出答案对ppp取模 ...

  2. 五颜六色的幻想乡 - 矩阵树定理 - 拉格朗日插值

    题目大意:给一张图,边有三种颜色,对于每一种可能的a+b+c=n-1的(a,b,c)问恰好a条红色边b条黄色c条蓝色边的方案数,n<=50,5s. 题解:朴素做法,红色视为x黄色视作y蓝色视作1 ...

  3. 矩阵树定理--luoguP4208 [JSOI2008]最小生成树计数

    传送门 以前用dfsdfsdfs做的,用基尔霍夫矩阵真的玄啊 首先这道题有这么几个定理:(来自Z-Y-Y-S的博客) 定理一:如果 A,BA, BA,B 同为 GGG 的最小生成树,且 AAA 的边权 ...

  4. 矩阵树定理2020HDU多校第6场j-Expectation[位运算+期望]

    矩阵树定理 用于求解图上面生成树的个数,生成树的个数等于基尔霍夫矩阵的任何一个N-1阶主子式的行列式的绝对值 矩阵树模板 struct Matrix_Tree {ll a[N][N];Matrix_T ...

  5. 行列式入门与矩阵树定理完整证明

    文章目录 前置技能 行列式 定义 性质 拉普拉斯展开 线性性 可乘性 可加性 不重性 可倍加性 转置不变性 可交换性 行可交换性 列可交换性 优化行列式的计算 矩阵树定理 前置定义 一些引理 转置引理 ...

  6. 最小生成树、矩阵树定理、Prufer序列总结

    Kruskal算法 按边权排序,从小到大合并不在同一集合两点即可 Prim算法 每次加入一个到当前已选点集最近的点 P2619 [国家集训队]Tree I 考虑二分,每次给白边加上一个mid,通过这种 ...

  7. [meet in middle 矩阵树定理 容斥原理] SRM 551 div1 SweetFruits

    集训队论文传送门 大概就是我们先用meet in middle求出有恰好k个真甜的方案数 然后我们求这些东西的生成树个数 乘在一起的和就是答案 我们让真甜连真甜 真甜连不甜 假甜连不甜 不甜连不甜 跑 ...

  8. Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理,子集反演)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理) Problem n≤1 ...

  9. 【学习笔记】矩阵树定理(Matrix-Tree)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 一.矩阵树定理 二.常用定理 三.例题 1. Luogu P6178 [模板]Matrix-Tr ...

最新文章

  1. Leetcode 215. 数组中的第K个最大元素 解题思路及C++实现
  2. 想成为BAT中的一员,你总要去学点什么(一)
  3. MyBatis 事务源码分析
  4. 02-eclipse中构建ant项目和编译运行ant
  5. laravel的foreach
  6. 训练集、验证集、测试集详解和极其作用
  7. php mysql 模型_ThinkPHP数据库与模型
  8. Android8.1根据app名字调用显示app的属性页(App info)
  9. 自定义id的几种思路分享以及税务单据编号实现
  10. SEGGER Embedded Studio 4.22 入门之:配合cubemx 快速建立ES工程
  11. 修改win10 ntp服务器地址,修改win10 ntp服务器地址
  12. 修复BUG的完整过程:Ignored attempt to cancel a touchend event with cancelable=false
  13. mysql表分区join_​实战:Flink 1.12 维表 Join Hive 最新分区功能体验
  14. Android手机卡顿原因
  15. 计算机建模与仿真心得,计算机建模与仿真.docx
  16. 海海软件发布HHMeet Android安卓测试版- 加密保护Zoom视频会议-手机直播防翻录
  17. oracle怎么查日记账,Oracle EBS 导入日记账报错
  18. 一个项目中不能同时出现两个main函数
  19. 迅为iMX6ULL开发板-创建 ap 热点
  20. php网店系统与java网店系统的区别

热门文章

  1. 算法设计与分析——贪心算法——多机调度问题
  2. android arp工具,GitHub - SummerSnow274/ARP_sed_rev: 在Android通过ARP询问实现获取同一网络所有设备的MAC地址,AP隔离的网络除外...
  3. leetcode104. 二叉树的最大深度(层序遍历09)
  4. 10-1 5-1 查询销售便携式电脑但不销售PC的厂商 (20 分)(分析+详解)
  5. 「软件项目管理」成本估算模型——Walston-Felix模型和COCOMO Ⅱ模型
  6. 『软件工程4』一文了解软件项目管理中的4P
  7. array remove java_how to remove array from another array in javascript
  8. [JavaWeb-XML]XML基本语法与快速入门
  9. C++vector容器-构造函数
  10. 网络编程-TCP/IP协议栈-TCP协议