最小生成树计数 模板 hdu 4408
题意是给定n个点,m条边的无向图,求最小生成树的个数对p取模。
用kruscal计算最小生成树时,每次取连接了两个不同联通块的最小的边。也就是先处理d1条c1长度的边,再处理d2条c2长度的边。长度相同的边无论怎么选,最大联通情况都是固定的。 分别对ci长度的边产生的几个联通块计算生成树数量再乘起来,然后把这些联通块缩点,再计算ci+1长度的边。
生成树计数用Matrix-Tree定理,上一篇是无重边的,这题的缩点后是会产生重边的,Matrix-tree也适用: //抄别人博客的
Kirchhoff矩阵任意n-1阶子矩阵的行列式的绝对值就是无向图的生成树的数量。
Kirchhoff矩阵的定义是度数矩阵-邻接矩阵。
1、G的度数矩阵D[G]:n*n的矩阵,Dii等于Vi的度数,其余为0。
2、G的邻接矩阵A[G]:n*n的矩阵, Vi、Vj之间有边直接相连,则 Aij=ij之间的边数,否则为0。
并查集fa[i]是当前长度之前,节点所属的联通块,ka[i]是当前长度的边连接后它在的联通块。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N=;
const int M=;
ll n,m,p,ans;
vector<int>gra[N];
struct edge{
int u,v,w;
}e[M];
int cmp(edge a,edge b){
return a.w<b.w;
}
ll mat[N][N],g[N][N];
ll fa[N],ka[N],vis[N];
ll det(ll c[][N],ll n){
ll i,j,k,t,ret=;
for(i=;i<n;i++)
for(j=;j<n;j++) c[i][j]%=p;
for(i=; i<n; i++){
for(j=i+; j<n; j++)
while(c[j][i]){
t=c[i][i]/c[j][i];
for(k=i; k<n; k++)
c[i][k]=(c[i][k]-c[j][k]*t)%p;
swap(c[i],c[j]);
ret=-ret;
}
if(c[i][i]==)
return 0L;
ret=ret*c[i][i]%p;
}
return (ret+p)%p;
}
ll find(ll a,ll f[]){
return f[a]==a?a:find(f[a],f);
}
void matrix_tree(){//对当前长度的边连接的每个联通块计算生成树个数
for(int i=;i<n;i++)if(vis[i]){//当前长度的边连接了i节点
gra[find(i,ka)].push_back(i);//将i节点压入所属的联通块
vis[i]=;//一边清空vis数组
}
for(int i=;i<n;i++)
if(gra[i].size()>){//联通块的点数为1时生成树数量是1
memset(mat,,sizeof mat);//清空矩阵
int len=gra[i].size();
for(int j=;j<len;j++)
for(int k=j+;k<len;k++){//构造这个联通块的矩阵(有重边)
int u=gra[i][j],v=gra[i][k];
if(g[u][v]){
mat[k][j]=(mat[j][k]-=g[u][v]);
mat[k][k]+=g[u][v];mat[j][j]+=g[u][v];
}
}
ans=ans*det(mat,gra[i].size()-)%p;
for(int j=;j<len;j++)fa[gra[i][j]]=i;//缩点
}
for(int i=;i<n;i++)
{
gra[i].clear();
ka[i]=fa[i]=find(i,fa);
}
}
int main(){
while(scanf("%lld%lld%lld",&n,&m,&p),n){
for(int i=;i<m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
u--;v--;
e[i]=(edge){u,v,w};
}
sort(e,e+m,cmp);
memset(g,,sizeof g);
ans=;
for(ll i=;i<n;i++)ka[i]=fa[i]=i;
for(ll i=;i<=m;i++){//边从小到大加入
if(i&&e[i].w!=e[i-].w||i==m)//处理完长度为e[i-1].w的所有边
matrix_tree();//计算生成树
ll u=find(e[i].u,fa),v=find(e[i].v,fa);//连的两个缩点后的点
if(u!=v)//如果不是一个
{
vis[v]=vis[u]=;
ka[find(u,ka)]=find(v,ka);//两个分量在一个联通块里。
g[u][v]++,g[v][u]++;//邻接矩阵
}
}
int flag=;
for(int i=;i<n;i++)if(fa[i]!=fa[i-])flag=;
printf("%lld\n",flag?ans%p:);//注意p可能为1,这样m=0时如果ans不%p就会输出1
}
}
最小生成树计数 模板 hdu 4408的更多相关文章
- 最小生成树计数 bzoj 1016
最小生成树计数 (1s 128M) award [问题描述] 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一 ...
- 【bzoj1016】 JSOI2008—最小生成树计数
http://www.lydsy.com/JudgeOnline/problem.php?id=1016 (题目链接) 题意 求图的最小生成树计数. Solution %了下题解,发现要写矩阵树,15 ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- 【BZOJ】【1016】【JSOI2008】最小生成树计数
Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
- BZOJ_1016_[JSOI2008]_最小生成树计数_(dfs+乘法原理)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1016 给出一张图,其中具有相同权值的边的数目不超过10,求最小生成树的个数. 分析 生成树的计 ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
随机推荐
- CPPU OJ | 开发日志
2019.12.18 ~ 2019.12.22 用腾讯云的学生服务器测试搭建OJ(踩了无数的坑) 2019.12.25 ~ 2019.12.28 在模管中心办理申请虚拟服务器的手续 2019.12.3 ...
- SpringMVC-简单参数绑定
SpringMVC-简单参数绑定 众所周知,springmvc是用来处理页面的一些请求,然后将数据再通过视图返回给用户的,前面的几篇博文中使用的都是静态数据,为了能快速入门springmvc,在 ...
- laravel多条件模糊查询
1.运用cmd在项目根目录下创建路由组 php artisan make:controller queryController --resource 1.1数据库信息(student) CREATE ...
- JS高级---浅拷贝
浅拷贝 拷贝就是复制, 就相当于把一个对象中的所有的内容, 复制一份给另一个对象, 直接复制, 或者说, 就是把一个对象的地址给了另一个对象, 他们指向相同, 两个对象之间有共同的属性或者方法, ...
- go语言 RSA数字签名和验证签名
package main import ( "crypto" "crypto/rand" "crypto/rsa" "crypto ...
- 运筹学学报-运行问题之新版TeX系统支持修改
<运筹学学报>的LaTeX模板基本上是CCT的典型而且是停留在LaTeX2.09 的时代,故而很多用户下载其模板无法在新TeX系统里使用,这里提供以下解决方案.源文件中的前几行:\docu ...
- HDU-1719 Friend
刚开始想打个表... 结果我发现我理解错了题目意思,以为a,b必须是两个不同的数字,然后完全无法理解样例的3为什么是friend number...很尴尬就只能去网上找题解,才发现a,b可以相等(太菜 ...
- 1054 The Dominant Color
大致题意就是给出N行M列的元素,找出出现次数最多的元素并输出. #include<iostream> #include<unordered_map> using namespa ...
- docker-machine之升级linux内核
虚拟机版本及内核信息 uname -a 或者 uname -r 开始升级内核 1.更新yum源 yum -y update 2,获取内核信息 rpm --import https://www.elre ...
- jsp中 EL表达式 ${}
原文位置:https://zhidao.baidu.com/question/711232806155434565.html jsp标签中的 ${表达式}用来输出或者计算一个表达式的内容,比如${3+ ...