大视野 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 ...
随机推荐
- 201621123080《Java程序设计》第1周学习总结
作业01-Java基本概念 1. 本周学习总结 关键词: JDK.JAVA.编程.基础语法 概念之间的关系: JDK是JAVA的开发工具,学习JAVA的主要方法是大量编程,语法是JAVA的基础 2. ...
- charles 模拟手机弱网、修改请求参数、修改返回值
1.charles模拟弱网(断网) 2.charles修改请求参数 (1)先访问一次需要改的请求,在charles上找到相应的请求地址 (2)然后在需要打断点的请求上右键,勾选[Breakpoints ...
- 学习路由器vue-router
vue-router:vue官方路由管理器. 功能:嵌套的路由/视图表模块化的.基于组件的路由配置路由参数.查询.通配符基于 Vue.js 过渡系统的视图过渡效果细粒度的导航控制带有自动激活的 CSS ...
- 使用laravel框架的eloquent\DB模型连接多个数据库
1.配置.env文件 DB_HOST_TRAILER=127.0.0.1DB_PORT_TRAILER=3306DB_DATABASE_TRAILER=htms_trailerDB_USERNAME_ ...
- linux中怎样关闭ICMP回应功能
引用自:http://blog.csdn.net/qq844352155/article/details/49700121 linux中怎样关闭ICMP回应功能 输入: echo 1 > ...
- python3 发邮件 smtplib & email 库
嗨 实现了用163发送到qq的功能,遗留了两个问题: 1. 接收者list会报错:update:因为list[]会传递过去一个真的[]list,改成如下就可以了: before: maillist=[ ...
- Linux集群之高可用负载均衡lvs+keepalived
LVS简介 LVS介绍 LVS是Linux Virtual Server的缩写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统,属于4层负载均衡 ipvs和ipvsadm的关系 我们使用配置LV ...
- 数学基础:HDU2802-F(N)(寻找循环节)
F(N) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- hdu 5533
Dancing Stars on Me Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Ot ...
- 设置eclipse中的${user}
打开eclipse根目录找到eclipse.ini文件增加初始配置: -Duser.name=snzigod@hotmail.com 重启eclipse后${user}变量的值就变成了snzigod@ ...