题目大意:给出一些边,求出一共能形成多少个最小生成树。

思路:最小生成树有非常多定理啊,我也不是非常明确。这里仅仅简单讲讲做法。关于定各种定理请看这里:http://blog.csdn.net/wyfcyx_forever/article/details/40182739

我们先做一次最小生成树。然后记录每一种长度的边有多少在最小生成树中,然后从小到大搜索,看每一种边权有多少种放法。然后全部的都算出来累乘就是终于的结果。

CODE:

#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 2010
#define MO 31011
using namespace std; map<int,int> G; struct Complex{
int x,y,len; bool operator <(const Complex &a)const {
return len < a.len;
}
void Read() {
scanf("%d%d%d",&x,&y,&len);
}
}edge[MAX]; int points,edges;
int ones[MAX]; int father[MAX];
int ans = 1; void Pretreatment()
{
for(int i = 1;i <= 1025; ++i)
ones[i] = ones[i >> 1] + (i&1);
} int Find(int x)
{
if(!father[x] || father[x] == x) return father[x] = x;
return father[x] = Find(father[x]);
} bool Kruskal()
{
int cnt = 0;
for(int i = 1;i <= edges; ++i) {
int fx = Find(edge[i].x);
int fy = Find(edge[i].y);
if(fx != fy) {
father[fy] = fx;
G[edge[i].len]++;
cnt++;
}
}
if(cnt < points - 1) return false;
return true;
} void DFS(int pos)
{
if(pos > edges) return ;
int st = pos,ed = pos,re = 0;
int cnt = G[edge[st].len];
if(!cnt) {
DFS(ed + 1);
return ;
}
while(edge[ed + 1].len == edge[st].len) ++ed;
for(int i = 0;i < (1 << (ed - st + 1)); ++i)
if(ones[i] == cnt) {
memset(father,0,sizeof(father));
int temp = i;
for(int j = st; temp; temp >>= 1,++j)
if(temp&1) {
int fx = Find(edge[j].x);
int fy = Find(edge[j].y);
if(fx == fy) break;
father[fy] = fx;
}
if(!temp) ++re;
}
ans = (ans * re) % MO;
memset(father,0,sizeof(father));
for(int i = st; i <= ed; ++i) {
int fx = Find(edge[i].x);
int fy = Find(edge[i].y);
if(fx == fy) continue;
father[fy] = fx;
}
for(int i = ed + 1;i <= edges; ++i)
edge[i].x = Find(edge[i].x),edge[i].y = Find(edge[i].y);
DFS(ed + 1);
} int main()
{
Pretreatment();
cin >> points >> edges;
for(int i = 1;i <= edges; ++i)
edge[i].Read();
sort(edge + 1,edge + edges + 1);
memset(father,0,sizeof(father));
if(!Kruskal()) {
cout << 0 << endl;
return 0;
}
DFS(1);
cout << ans << endl;
return 0;
}

BZOJ 1016 JSOI 2008 最小生成树计数 Kruskal+搜索的更多相关文章

  1. JSOI 2008 最小生成树计数

    JSOI 2008 最小生成树计数 今天的题目终于良心一点辣 一个套路+模版题. 考虑昨天讲的那几个结论,我们有当我们只保留最小生成树中权值不超过 $ k $ 的边的时候形成的联通块是一定的. 我们可 ...

  2. 【BZOJ 1016】[JSOI2008]最小生成树计数(搜索+克鲁斯卡尔)

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 [题意] [题解] /* 两个最小生成树T和T'; 它们各个边权的边的数目肯定是 ...

  3. 【BZOJ 1016】 [JSOI2008]最小生成树计数(matrix-tree定理做法)

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 [题意] [题解] /* 接上一篇文章; 这里用matrix-tree定理搞最小 ...

  4. [BZOJ 1013][JSOI 2008] 球形空间产生器sphere 题解(高斯消元)

    [BZOJ 1013][JSOI 2008] 球形空间产生器sphere Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面 ...

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

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

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

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

  7. [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)

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

  8. [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)

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

  9. bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)

    由于有相同权值的边不超过10条的限制,所以可以暴搜 先做一遍kruskal,记录下来每个权值的边使用的数量(可以离散化一下) 可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的.而且它们连成 ...

随机推荐

  1. 蓝牙遥控小车设计(四)——Android APP遥控

    最近都没心情写博客,忙着答辩论文之类的,唉,主要是愁工作啊...... 先上车体全景图: APP截图: 上最终视频:

  2. spark技术热点问题互动问答

    决胜云计算大数据时代” Spark亚太研究院100期公益大讲堂 [第4期互动问答分享]  Q1:Spark SQL和Shark有啥区别? Shark需要依赖于Hadoop上Hive去做SQL语句的解析 ...

  3. HDU 多校1.4

    Division Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  4. NOIP2014飞扬的小鸟

    长为n,高为m的二维平面,其中有k个管道(忽略管道的宽度)小鸟始终在游戏界面内移动.从最左边任意高度位置出发,到达游戏界面最右边,游戏完成每个单位时间沿横坐标方向右移距离为1,竖直移动的距离由玩家控制 ...

  5. Linux命令之install

    install [选项] 源文件 目标文件 install [选项] 源文件 目录 install [选项] –t 目录 源文件 install [选项] –d 目录 install作用是安装或升级软 ...

  6. CentOS下MySQL主从复制,读写分离

    1.环境:所有系统都是CentOS5.5 mysql-5.6.31-2.el5,MySQL中都没有数据 主服务器IP为192.168.128.230 从服务器IP为192.168.128.235 代理 ...

  7. C++ 对象的内存布局【转】

    单一继承: 虚函数表在最前面的位置. 成员变量根据其继承和声明顺序依次放在后面. 在单一的继承中,被overwrite的虚函数在虚函数表中得到了更新. 多重继承 每个父类都有自己的虚表. 子类的成员函 ...

  8. sed 概述

    sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送 ...

  9. 小型Web应用扫描工具Grabber

    小型Web应用扫描工具Grabber   Grabber是Kali Linux集成的一款Web应用扫描工具.该工具适合中小Web应用,如个人博客.论坛等.该工具使用Python语言编写,支持常见的漏洞 ...

  10. luogu P1215 [USACO1.4]母亲的牛奶 Mother's Milk

    题目描述 农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的.有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了 ...