Problem Description
XXX is very interested in algorithm. After learning the
Prim algorithm and Kruskal algorithm of minimum spanning tree, XXX finds that
there might be multiple solutions. Given an undirected weighted graph with n
(1<=n<=100) vertexes and m (0<=m<=1000) edges, he wants to know the
number of minimum spanning trees in the graph.
 
Input
There are no more than 15 cases. The input ends by 0 0
0.
For each case, the first line begins with three integers --- the above
mentioned n, m, and p. The meaning of p will be explained later. Each the
following m lines contains three integers u, v, w (1<=w<=10), which
describes that there is an edge weighted w between vertex u and vertex v( all
vertex are numbered for 1 to n) . It is guaranteed that there are no multiple
edges and no loops in the graph.
 
Output
For each test case, output a single integer in one line
representing the number of different minimum spanning trees in the graph.
The
answer may be quite large. You just need to calculate the remainder of the
answer when divided by p (1<=p<=1000000000). p is above mentioned, appears
in the first line of each test case.
Sample Input
5 10 12
2 5 3
2 4 2
3 1 3
3 4 2
1 2 3
5 4 3
5 1 3
4 1 1
5 3 3
3 2 3
0 0 0
 
Sample Output
4
 
Source
 
 
题意:求最小生成树的数量
 
矩阵树定理
 
回想 Kruskal算法,从小到大枚举边
当边权相等时,边随意排序
那么当权值为k的边全部枚举完后,点的联通情况F是固定的
也就是说权值都为k的边无论以什么顺序枚举,得到的生成树的形态不一,但联通情况F'和F相同
如果将加入最小生成树的 权值为1——k-1的边 和 对应的点 压缩成一个点,
所有权值为k 的边 的联通情况 是独立的
根据乘法原理
我们可以枚举权值k
计算此时形成F的方案数 
具体来说就是 枚举权值为k的边形成的连通块,用矩阵树定理算出每种连通块的方案数
累乘就是权值为k的边形成F的方案数
最后将所有权值为k的边的答案累乘
 
注意 并查集不要路径压缩
因为矩阵树定理需要每个点的度数

#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,mod;
int fa[],ka[];
struct node
{
int u,v,w;
}e[];
int a[][];
bool vis[];
vector<int>g[];
long long ans,C[][],t;
bool cmp(node p,node q)
{
return p.w<q.w;
}
int find(int i,int *f) { return f[i]==i ? i : find(f[i],f); }
bool init()
{
int u,v;
scanf("%d%d%d",&n,&m,&mod);
if(!n) return false;
for(int i=;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
return true;
}
long long det(int h)
{
long long s=;
for(int i=;i<h;i++)
{
for(int j=i+;j<h;j++)
while(C[j][i])
{
t=C[i][i]/C[j][i];
for(int k=i;k<h;k++) C[i][k]=(C[i][k]-C[j][k]*t+mod)%mod;
for(int k=i;k<h;k++) swap(C[i][k],C[j][k]);
s=-s;
}
s=s*C[i][i]%mod;
if(!s) return ;
}
return (s+mod)%mod;
}
void matrix_tree()
{
int len,u,v;
for(int i=;i<=n;i++)
if(vis[i])
{
g[find(i,ka)].push_back(i);
vis[i]=false;
}
for(int i=;i<=n;i++)
if(g[i].size())
{
memset(C,,sizeof(C));
len=g[i].size();
for(int j=;j<len;j++)
for(int k=j+;k<len;k++)
{
u=g[i][j]; v=g[i][k];
if(a[u][v])
{
C[k][j]=(C[j][k]-=a[u][v]);
C[k][k]+=a[u][v]; C[j][j]+=a[u][v];
}
}
ans=ans*det(g[i].size()-)%mod;
for(int j=;j<len;j++) fa[g[i][j]]=i;
}
for(int i=;i<=n;i++)
{
g[i].clear();
ka[i]=find(i,fa);
}
}
void solve()
{
ans=;
int u,v;
memset(a,,sizeof(a));
for(int i=;i<=n;i++) fa[i]=ka[i]=i;
sort(e+,e+m+,cmp);
for(int i=;i<=m+;i++)
{
if(e[i].w!=e[i-].w && i!= || i==m+) matrix_tree();
u=find(e[i].u,fa); v=find(e[i].v,fa);
if(u!=v)
{
vis[u]=vis[v]=true;
ka[find(u,ka)]=find(v,ka);
a[u][v]++; a[v][u]++;
}
}
bool flag=true;
for(int i=;i<n && flag;i++)
if(find(i,fa)!=find(i+,fa)) flag=false;
printf("%lld\n",flag ? ans%mod : );
}
int main()
{
while(init()) solve();
}

 
 

hdu 4408 Minimum Spanning Tree的更多相关文章

  1. HDU 4408 Minimum Spanning Tree 最小生成树计数

    Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. 【HDU 4408】Minimum Spanning Tree(最小生成树计数)

    Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...

  3. 多校 HDU - 6614 AND Minimum Spanning Tree (二进制)

    传送门 AND Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  4. 数据结构与算法分析–Minimum Spanning Tree(最小生成树)

    给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(spanning tree). 如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST,Mi ...

  5. Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST

    E. Minimum spanning tree for each edge   Connected undirected weighted graph without self-loops and ...

  6. CF# Educational Codeforces Round 3 E. Minimum spanning tree for each edge

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  7. Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值

    E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...

  8. MST(Kruskal’s Minimum Spanning Tree Algorithm)

    You may refer to the main idea of MST in graph theory. http://en.wikipedia.org/wiki/Minimum_spanning ...

  9. [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]

    这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...

随机推荐

  1. Notes of the scrum meeting(12.11)

    meeting time:19:30~20:30p.m.,December 11th,2013 meeting place:3号公寓一层 attendees: 顾育豪                  ...

  2. 软工实践-Alpha 冲刺 (1/10)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 学习了UI设计软件的使用,了解了项目开发的具体流程. 展示 ...

  3. scrapy(2)——scrapy爬取新浪微博(单机版)

    Sina爬虫教程   Scrapy环境搭建   环境:window10 + python2.7(包含scrapy)+ mongoDB 1.1 安装集成了python2.7的anaconda   ana ...

  4. LINUX硬件查看命令

    1.查看系统PCI设备 lspci lspci -v   显示更详细的PCI设备信息 2.查看CPU信息 more / proc /cpuinfo 3.查看系统内存信息 more /proc /mem ...

  5. 网络编程--System.Net

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. ManagementClass("Win32_Share")之共享目录

    public class ShareFolder { private static readonly Dictionary<uint, string> ReturnDetails = ne ...

  7. DDL、DML和DCL的比较【引用学习】

    1.DDL       1-1.DDL的概述                DDL(Data Definition Language 数据定义语言)用于操作对象和对象的属性,这种对象包括数据库本身,以 ...

  8. FTP-成型版本

    1. 旧知识回顾-反射 hasattr(object, name) 说明:判断对象object是否包含名为name的属性(方法) 测试代码如下: class tt(object): def __ini ...

  9. 【刷题】BZOJ 3546 [ONTAK2010]Life of the Party

    Description 一个舞会有N个男孩(编号为1..N)和M个女孩(编号为1..M),一对男女能够组成一对跳舞当且仅当他们两个人互相认识. 我们把一种人定义成这个舞会的life:当且仅当如果他(她 ...

  10. [洛谷P4847]银河英雄传说V2

    题目大意:有$n(n\leqslant2\times10^5)$个序列,有$m(m\leqslant2\times10^5)$个操作,分三种: 1. $M\;x\;y:$把$x$所在的序列放在$y$所 ...