大视野 1016: [JSOI2008]最小生成树计数(最小生成树)
总结:此类题需要耐心观察规律,大胆猜想,然后证明猜想,得到有用的性质,然后解答。 简单的说:找隐含性质。
传送门: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]最小生成树计数(最小生成树)的更多相关文章
- BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- [BZOJ1016][JSOI2008]最小生成树计数 最小生成树 搜索
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 做这道题之前需要知道一些结论,同一个图的最小生成树中相同权值的边的个数是不会变的,如 ...
- 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理
蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...
- $bzoj1016-JSOI2008$ 最小生成树计数 最小生成树 $dfs/matrix-tree$定理
题面描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的).由于不同的 ...
- BZOJ1016最小生成树计数 最小生成树 + 排列组合
@[最小生成樹, 排列組合] Discription 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的 最小生成树.(如果两颗最小生成树中至少有一条边不 ...
- 大视野 1012: [JSOI2008]最大数maxnumber(线段树/ 树状数组/ 单调队列/ 单调栈/ rmq)
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 9851 Solved: 4318[Submi ...
- 【BZOJ】【1016】【JSOI2008】最小生成树计数
Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
随机推荐
- [LOJ] #2360. 「NOIP2016」换教室
期望DP #include<iostream> #include<cstring> #include<cstdio> #include<cctype> ...
- Windows7设置局域网文件共享
首先要实现共享必须设置共享的机器与访问共享的机器在同一个工作组中. 右键桌面上的计算机图标=>属性 如果不一样的话,就需要点击[更改设置] 右键要共享的文件或者文件夹,点击[共享]打开共享标签: ...
- LVS-nat模式-原理介绍
集群,为解决某个特定问题将多台计算机组合起来形成的单个系统 lvs-nat: 本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发 lvs集群类 ...
- NodeJS基础入门-fs文件系统
文件I/O是由简单封装的标准POSIX函数提供.通过require('fs') 使用该模块.所有的方法都有异步和同步的形式. 异步方法的最后一个参数都是一个回调函数.传给回调函数的参数取决于具体方法, ...
- Python——format汇总
一.str.format 按照指定格式格式化字符串,然后返回格式化的字符串,源字符串不变. 以下是Python2.7环境. 1.1.按照位置替换 参考下面例子: >>> s = '{ ...
- virtualbox安装win7系统报错(“FATAL:No bootable medium found!”)
virtualbox属于傻瓜式安装虚拟系统,但博主安装win7系统时,无论怎么调试都还是出现截图所述样式,网上教程很多,但是都不行,其实只有一个根本原因安装的iso镜像不是原生镜像,下载的镜像已经是被 ...
- C# NotifyIcon 托盘控件
右下角以图标形式显示,双击图标显示界面,最小化界面时不显示在任务栏. 第一步:在界面上添加NotifyIcon控件. 第二步:设置notifyIcon1的属性,添加图标,将Visible设为true. ...
- java/jsp执行sql语句的方式
首先给出sql驱动包 引入sql包 import java.sql.*;//java <%@ page import="java.sql.*"%>//jsp 连接mys ...
- AreYouBusy HDU - 3535 (dp)
AreYouBusy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu-1338 game predictions(贪心题)
Suppose there are M people, including you, playing a special card game. At the beginning, each playe ...