[XSY]Tree Ext(矩阵树定理,拉格朗日插值,最小生成树,二分)
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(矩阵树定理,拉格朗日插值,最小生成树,二分)相关推荐
- Wannafly挑战赛23F-计数【原根,矩阵树定理,拉格朗日插值】
正题 题目链接:https://ac.nowcoder.com/acm/contest/161/F 题目大意 给出nnn个点的一张图,求它的所有生成树中权值和为kkk的倍数的个数.输出答案对ppp取模 ...
- 五颜六色的幻想乡 - 矩阵树定理 - 拉格朗日插值
题目大意:给一张图,边有三种颜色,对于每一种可能的a+b+c=n-1的(a,b,c)问恰好a条红色边b条黄色c条蓝色边的方案数,n<=50,5s. 题解:朴素做法,红色视为x黄色视作y蓝色视作1 ...
- 矩阵树定理--luoguP4208 [JSOI2008]最小生成树计数
传送门 以前用dfsdfsdfs做的,用基尔霍夫矩阵真的玄啊 首先这道题有这么几个定理:(来自Z-Y-Y-S的博客) 定理一:如果 A,BA, BA,B 同为 GGG 的最小生成树,且 AAA 的边权 ...
- 矩阵树定理2020HDU多校第6场j-Expectation[位运算+期望]
矩阵树定理 用于求解图上面生成树的个数,生成树的个数等于基尔霍夫矩阵的任何一个N-1阶主子式的行列式的绝对值 矩阵树模板 struct Matrix_Tree {ll a[N][N];Matrix_T ...
- 行列式入门与矩阵树定理完整证明
文章目录 前置技能 行列式 定义 性质 拉普拉斯展开 线性性 可乘性 可加性 不重性 可倍加性 转置不变性 可交换性 行可交换性 列可交换性 优化行列式的计算 矩阵树定理 前置定义 一些引理 转置引理 ...
- 最小生成树、矩阵树定理、Prufer序列总结
Kruskal算法 按边权排序,从小到大合并不在同一集合两点即可 Prim算法 每次加入一个到当前已选点集最近的点 P2619 [国家集训队]Tree I 考虑二分,每次给白边加上一个mid,通过这种 ...
- [meet in middle 矩阵树定理 容斥原理] SRM 551 div1 SweetFruits
集训队论文传送门 大概就是我们先用meet in middle求出有恰好k个真甜的方案数 然后我们求这些东西的生成树个数 乘在一起的和就是答案 我们让真甜连真甜 真甜连不甜 假甜连不甜 不甜连不甜 跑 ...
- Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理,子集反演)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理) Problem n≤1 ...
- 【学习笔记】矩阵树定理(Matrix-Tree)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 一.矩阵树定理 二.常用定理 三.例题 1. Luogu P6178 [模板]Matrix-Tr ...
最新文章
- Leetcode 215. 数组中的第K个最大元素 解题思路及C++实现
- 想成为BAT中的一员,你总要去学点什么(一)
- MyBatis 事务源码分析
- 02-eclipse中构建ant项目和编译运行ant
- laravel的foreach
- 训练集、验证集、测试集详解和极其作用
- php mysql 模型_ThinkPHP数据库与模型
- Android8.1根据app名字调用显示app的属性页(App info)
- 自定义id的几种思路分享以及税务单据编号实现
- SEGGER Embedded Studio 4.22 入门之:配合cubemx 快速建立ES工程
- 修改win10 ntp服务器地址,修改win10 ntp服务器地址
- 修复BUG的完整过程:Ignored attempt to cancel a touchend event with cancelable=false
- mysql表分区join_​实战:Flink 1.12 维表 Join Hive 最新分区功能体验
- Android手机卡顿原因
- 计算机建模与仿真心得,计算机建模与仿真.docx
- 海海软件发布HHMeet Android安卓测试版- 加密保护Zoom视频会议-手机直播防翻录
- oracle怎么查日记账,Oracle EBS 导入日记账报错
- 一个项目中不能同时出现两个main函数
- 迅为iMX6ULL开发板-创建 ap 热点
- php网店系统与java网店系统的区别
热门文章
- 算法设计与分析——贪心算法——多机调度问题
- android arp工具,GitHub - SummerSnow274/ARP_sed_rev: 在Android通过ARP询问实现获取同一网络所有设备的MAC地址,AP隔离的网络除外...
- leetcode104. 二叉树的最大深度(层序遍历09)
- 10-1 5-1 查询销售便携式电脑但不销售PC的厂商 (20 分)(分析+详解)
- 「软件项目管理」成本估算模型——Walston-Felix模型和COCOMO Ⅱ模型
- 『软件工程4』一文了解软件项目管理中的4P
- array remove java_how to remove array from another array in javascript
- [JavaWeb-XML]XML基本语法与快速入门
- C++vector容器-构造函数
- 网络编程-TCP/IP协议栈-TCP协议