描述


http://www.lydsy.com/JudgeOnline/problem.php?id=1016

给出一张图,其中具有相同权值的边的数目不超过10,求最小生成树的个数.

分析


生成树的计数有一个什么什么算法...

我真的企图研究了...但是智商捉急的我实在看不懂论文...

所以最后还是写了暴力...

当然暴力也要靠正确的姿势的.

首先来看一个结论:

同一张图的所有最小生成树中,边权值相同的边的数目是一定的.

也就是说,假如某一张图的某一棵最小生成树由边权值为1,1,2,2,2,3的边组成,那么这张图的所有其他最小生成树也都由六条权值分别为1,1,2,2,2,3的边组成.

至于证明,我们可以用数学归纳法.

1.以上结论对与n=2的情况显然成立.

2.假设对于n=k的情况以上结论成立即k个节点的最小生成树满足相同权值的边的数目一定.那么对于n=k+1的情况,需要加一条边将第k+1个点连起来,因为生成树是最小的,所以所加的边的权值是一定的,而之前的k-1条边(连接之前的k个点的边)各权值的边的数目也是一定的,所以最终各权值的边的数目是一定的.

有了这样的一个结论,又因为相同权值的边的数目不超过10,所以我们就可以利用暴力dfs+乘法原理,统计每一种权值的边的选择的方案数,然后相乘即可.

 #include <bits/stdc++.h>
using namespace std; const int maxn=+,maxm=+,mod=;
struct edge{
int u,v,w;
edge(){}
edge(int u,int v,int w):u(u),v(v),w(w){}
bool operator < (const edge &a) const { return w<a.w; }
}g[maxm];
int n,m,cnt,sum,ans=;
int a[maxm],b[maxm],ect[maxm],f[maxn];
inline int read(int &x){x=;int k=;char c;for(c=getchar();c<''||c>'';c=getchar())if(c=='-')k=-;for(;c>=''&&c<='';c=getchar())x=x*+c-'';return x*=k;}
inline int find(int x){return x==f[x]?x:find(f[x]);}
void dfs(int s,int t,int rem){
if(rem==){
sum++;
return;
}
for(int i=s;i-+rem<=t;i++){
int fv=find(g[i].v),fu=find(g[i].u);
if(fu!=fv){
int F=f[fu];
f[fu]=fv;
dfs(i+,t,rem-);
f[fu]=F;
}
}
}
inline void solve(){
int i,j;
for(i=,j=;i<=m&&j<n;i++){
int fu=find(g[i].u),fv=find(g[i].v);
if(fu!=fv){
f[fu]=fv;
ect[b[i]]++;
j++;
}
}
if(j<n){
puts("");
return;
}
for(int i=;i<=n;i++) f[i]=i;
for(i=;i<=cnt;i++){
sum=;
dfs(a[i],a[i+]-,ect[i]);
for(int j=a[i];j<a[i+];j++){
int fu=find(g[j].u),fv=find(g[j].v);
if(fu!=fv) f[fu]=fv;
}
ans=(ans*sum)%mod;
}
printf("%d\n",ans);
}
inline void init(){
read(n); read(m);
for(int i=;i<=n;i++) f[i]=i;
for(int i=,u,v,w;i<=m;i++){
read(u); read(v); read(w);
g[i]=edge(u,v,w);
}
sort(g+,g++m);
for(int i=;i<=m;i++){
if(g[i].w!=g[i-].w) a[++cnt]=i;
b[i]=cnt;
}
a[cnt+]=m+;
}
int main(){
init();
solve();
return ;
}

1016: [JSOI2008]最小生成树计数

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4666  Solved: 1890
[Submit][Status][Discuss]

Description

  现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的
最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生
成树可能很多,所以你只需要输出方案数对31011的模就可以了。

Input

  第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整
数编号。接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,0
00。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。

Output

  输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。

Sample Input

4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1

Sample Output

8

HINT

Source

BZOJ_1016_[JSOI2008]_最小生成树计数_(dfs+乘法原理)的更多相关文章

  1. BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )

    不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...

  2. bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)

    1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等  就是说如果一种方案中权值为1的边有n条 ...

  3. 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)

    1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...

  4. 【BZOJ】【1016】【JSOI2008】最小生成树计数

    Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...

  5. [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】

    题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...

  6. bzoj 1016: [JSOI2008]最小生成树计数【dfs+克鲁斯卡尔】

    有一个性质就是组成最小生成树总边权值的若干边权总是相等的 这意味着按边权排序后在权值相同的一段区间内的边能被选入最小生成树的条数是固定的 所以先随便求一个最小生成树,把每段的入选边数记录下来 然后对于 ...

  7. BZOJ 1016 【JSOI2008】 最小生成树计数

    Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...

  8. 【BZOJ1016】【JSOI2008】最小生成树计数

    Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...

  9. BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1833 统计\(a~b\)中数字\(0,1,2,...,9\)分别出现了多少次. 分析 数位dp ...

随机推荐

  1. 如何从零开始实现一个soa远程调用服务基础组件

    说起soa远程调用基础组件,最著名的莫过于淘宝的dubbo了,目前很多的大型互联网公司都有一套自己的远程服务调用分布式框架,或者是使用开源的(例如dubbo),或者是自己基于某种协议(例如hessia ...

  2. 只有PD号的调起

    cicsterm-> CECI -> LI-> P -> TestQuery

  3. 关于MessageBox的用法

    今天编写MFC工程的时候,使用MessageBox函数,老是出错,不断从网上查找解决方案,最后找到了 MessageBox( _T("Help, Something went wrong.& ...

  4. 九度OJ 1214 寻找丑数【算法】

    题目地址:http://ac.jobdu.com/problem.php?pid=1214 题目描述: 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因 ...

  5. centos 7.0 mono&Jexus V5.5.3安装

    首先我们需要先配置一下yum源中mono的引用说明: 第一步: vi /etc/yum.repos.d/mono.repo 第二步:在刚打开的文件中编辑如下内容 [mono]name=monobase ...

  6. iOS之内存管理浅谈

    1.何为ARC ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release.在对象被创建时retain count+1,在对象被re ...

  7. Git问题:Cannot update paths and switch to branch 'dev' at the same time.

    使用命令 $ git checkout -b develop origin/develop 签出远程分支,出现以下错误: fatal: Cannot update paths and switch t ...

  8. 11个有用的Linux命令

    Linux命令行吸引了大多数Linux爱好者.一个正常的Linux用户一般掌握大约50-60个命令来处理每日的任务.今天为你解释下面几个命令:sudo.python.mtr.Ctrl+x+e.nl.s ...

  9. PERL代码摘录

    1. 语法与数据结构 #嵌套哈希的赋值和取值 $HashTable{$key} = [@Array] #这个是赋值 @Array = @{ $HashTable{$key} } # 这个是取值 #Pe ...

  10. 成为Java GC专家(4)—Apache的MaxClients参数详解及其在Tomcat执行FullGC时的影响

    下面我们看一下Apache的 MaxClients 参数在Full GC 发生时是如何影响系统的. 大部分开发人员都知道在由于GC发生而导致的”停止世界现象(STW) “(详细请参见Understan ...