总结:此类题需要耐心观察规律,大胆猜想,然后证明猜想,得到有用的性质,然后解答。 简单的说:找隐含性质。

传送门:http://61.187.179.132/JudgeOnline/problem.php?id=1016

题意:n个点m条边的图,问其最小生成树的个数(只要有一条边不同,就算不同)。n<100, m<1000 权值c < 10^9, 其中权相同的边的数量不会超过10条。

思路:

经过观察思考,得到以下结论:

任意两个最小生成树,将其所有边的边长排序后,将得到完全相同的结果。

意思是:只能用相同长度的边来代替,借此得到不同的最小生成树。

又因为每种权相同的边数不超过10,则可以用以下方法:

首先,生成一个最小生成树,得到其包含的所有权值以及数量。

其次,将其中某种权值的边删除,然后在图中取出所有权值相同的边, 状态压缩暴力匹配。得到这种边可以组合的方案数。

将所有权值的边的方案数相乘,就得到答案。

时间复杂度:MlogM + n(2^10*n) + M

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mod 31011
#define N 200 struct Edge{
int a, b, c;
bool operator < (const Edge &b) const {
return c < b.c;
}
}e[], mintre[]; struct BCJ{
int fa[N];
void init(int n) {
for (int i = ; i <= n; i++) {
fa[i] = i;
}
}
int find(int u) {
return fa[u]== u ? fa[u] : fa[u] = find(fa[u]);
}
void unin(int u, int v) {
fa[find(v)] = find(u);
}
}b; int main() {
int n, m;
while (scanf("%d%d", &n, &m) != EOF) {
for (int i = ; i < m; i++) {
scanf("%d%d%d", &e[i].a, &e[i].b, &e[i].c);
}
sort(e, e+m);
int top = ;
b.init(n);
for (int i = ; i < m; i++) {
if (b.find(e[i].a) != b.find(e[i].b)) {
b.unin(e[i].a, e[i].b);
mintre[top++] = e[i];
}
}
if (top != n-) {
puts("");
continue;
} int minp = ;
int ep = ;
int ans = ;
while (true) {
if (minp == top || ep == m) break;
int nowc = mintre[minp].c;
//printf("nowc = %d\n", nowc);
BCJ nowTong;
nowTong.init(n);
for (int i = ; i < top; i++) {
if (mintre[i].c != nowc) {
nowTong.unin(mintre[i].a, mintre[i].b);
}
} int edgeNum = ;
while (ep < m && e[ep].c < nowc) ep++;
while (ep < m && e[ep].c == nowc) {
edgeNum++;
ep++;
} int nownum = ;
while (minp < top && mintre[minp].c == nowc) {
nownum++;
minp++;
}
if (edgeNum == nownum) continue;
int end = (<<edgeNum);
int nowans = ;
BCJ tmpTong;
for (int i = ; i < end; i++) {
int tmpi = i;
int num = ;
while (tmpi) {
num += (tmpi&);
tmpi>>=;
}
if (num != nownum) continue; tmpTong = nowTong;
tmpi = i;
int unintime = ;
for (int j = ep-; e[j].c == nowc; j--) {
if (tmpi&) {
if (tmpTong.find(e[j].a) != tmpTong.find(e[j].b)) {
unintime++;
tmpTong.unin(e[j].a, e[j].b);
}
}
tmpi>>=;
}
if (unintime == nownum) {
nowans++;
}
}
ans *= nowans;
ans %= mod;
}
printf("%d\n", ans);
}
return ;
}

大视野 1016: [JSOI2008]最小生成树计数(最小生成树)的更多相关文章

  1. BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)

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

  2. [BZOJ1016][JSOI2008]最小生成树计数 最小生成树 搜索

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 做这道题之前需要知道一些结论,同一个图的最小生成树中相同权值的边的个数是不会变的,如 ...

  3. 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理

    蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...

  4. $bzoj1016-JSOI2008$ 最小生成树计数 最小生成树 $dfs/matrix-tree$定理

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

  5. BZOJ1016最小生成树计数 最小生成树 + 排列组合

    @[最小生成樹, 排列組合] Discription 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的 最小生成树.(如果两颗最小生成树中至少有一条边不 ...

  6. 大视野 1012: [JSOI2008]最大数maxnumber(线段树/ 树状数组/ 单调队列/ 单调栈/ rmq)

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 9851  Solved: 4318[Submi ...

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

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

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

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

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

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6200  Solved: 2518[Submit][St ...

随机推荐

  1. PAT 乙级 1048

    题目 题目地址:PAT 乙级 1048 思路 这道题坑的地方在于:即使B的长度小于A,仍然要对B补齐,也就是说最终结果的长度取决于A和B中长度更长的那一项:即只要A.B长度不一致,就要对短的一个进行补 ...

  2. Docker 容器的网络连接 & 容器互联

    1. Docker 容器网络基础架构 Docker0 ifconfig查看到的 docker0 是linux的虚拟网桥(OSI数据链路层) docker0 地址划分: 172.17.42.1 255. ...

  3. ise与win8兼容解决方案

    win8中ise无法加载code,显示impact4.exe停止运行. 解决方法如下: 找到程序安装路径 1.进入文件夹  D:\Xilinx\14.6\ISE_DS\ISE\lib\nt64 把li ...

  4. 将php数组转js数组,js如何接收PHP数组,json的用法

    首先下载下面这个文件(这是一段是别人写出来专门解析json的代码),然后引入这个文件! http://pan.baidu.com/s/1dD8qVr7 现在当我们需要用ajax与后台进行交互时,怎样将 ...

  5. Applied Nonparametric Statistics-lec6

    Ref: https://onlinecourses.science.psu.edu/stat464/print/book/export/html/8 前面都是对一两个样本的检查,现在考虑k个样本的情 ...

  6. leetcode-10-basic

    35. Search Insert Position Given a sorted array and a target value, return the index if the target i ...

  7. SDUST第十一次oj作业液晶显示问题

    Problem H: 液晶显示 Time Limit: 1 Sec  Memory Limit: 32 MBSubmit: 3246  Solved: 1594[Submit][Status][Web ...

  8. HDU 4781 Assignment For Princess 构造

    题意: 构造一个\(N(10 \leq N \leq 80)\)个顶点\(M(N+3 \leq M \leq \frac{N^2} {7})\)条边的有向图,要满足如下条件: 每条边有一个\([1,M ...

  9. TensorFlow笔记——

    主要依赖包 protocal buffer 处理结构化数据的工具:序列化(结构化数据->数据流) + 还原(数据流->结构化数据) protocol buffer与XML和JSON的区别: ...

  10. JAVA-STRUTS-2x的项目配置

    首先是web.xml的配置,这个是项目加载的开始. <display-name></display-name> <!--struts2配置开始--> <fil ...