全连通图求最小生成树边权之积(邻接矩阵/prim/kruskal)
Description
大家都知道最小生成树一般求的是构成最小生成树的边的权值之和。
现在请求构成最小生成树的边的权值之积 S,最终结果请输出 (S % 100003)。
P.S. 点之间的边为无向边,矩阵保证符合无向图的对称性。
Input
多组数据。
第一行,整数N,表示N个点。(0 < N <= 100)
接下来为一个N*N 保证合法的邻接矩阵,矩阵内均为自然数。
Output
每组数据输出一行整数结果。
Sample Input
3
0 1 2
1 0 3
2 3 0
2
0 5
5 0
Prim
#include<iostream>
#include<cstring>
using namespace std; #define MAX 105
#define INF 0x7FFFFFFF
int map[MAX][MAX]; // adjacency matrix
bool vis[MAX]; // is the node i visited
int dis[MAX]; // distance between current node and other node i void prim(int n) {
memset(vis, false, sizeof(vis)); // current node is 0
int cur = ;
for (int i = ; i < n; ++i)
dis[i] = map[cur][i]; // dis[] store distance between other nodes and 0
vis[cur] = true; unsigned long long s = ;
for (int i = ; i < n - ; ++i) {
// find the shortest edge between cur and other unvisited nodes
int min = INF;
for(int j = ; j < n; ++j)
if (!vis[j] && dis[j] < min)
min = dis[cur = j]; // update to next shortest edge and potential cur // the other end is visited and is now current node
s *= min;
s %= ;
vis[cur] = true; // update dis[] to store distance between other nodes and cur
// if the node is visited, leave it
for (int j = ; j < n; ++j)
if (!vis[j] && map[cur][j] < dis[j])
dis[j] = map[cur][j];
}
cout << (s % ) << endl;
} int main() {
int n; while(scanf("%d", &n) != EOF) {
for (int i = ; i < n; ++i)
for (int j = ; j < n; ++j)
scanf("%d", &map[i][j]);
prim(n);
} return ;
}
Kruskal,其实改装成了边表,加了并查集,有做路径压缩,可以水过就懒得写带rank的优化了……
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std; #define MAX 105
#define INF 0x7FFFFFFF int root[MAX];
int map[MAX][MAX]; struct Edge {
int u, v;
int d;
} e[MAX*MAX]; bool cmp(Edge a, Edge b) {
return a.d < b.d;
} int find(int x) {
while(x != root[x]) {
root[x] = root[root[x]]; // compress
x = root[x];
}
return x;
} unsigned long long kruskal(int vn, int en) {
unsigned long long p = ; // connect to itself
for (int i = ; i < vn; ++i)
root[i] = i; // sort edges by length
std::sort(e, e+en, cmp); for(int i = ; i < en; ++i) {
int ru = find(e[i].u);
int rv = find(e[i].v);
if(ru != rv) { // the ends of e[i] are not in the same spanning tree
root[ru] = rv; // merge
p *= e[i].d;
p %= ;
}
} return p;
} int main() {
int vn;
while(cin >> vn) {
memset(map, , sizeof(map));
for(int i = ; i < vn; ++i)
for(int j = ; j < vn; ++j)
cin >> map[i][j]; int en = ;
for(int i = ; i < vn; ++i) // use upper-right corner
for(int j = i + ; j < vn; ++j) {
// transform to adjacency list
e[en].u = i;
e[en].v = j;
e[en].d = map[i][j];
++en;
}
cout << kruskal(vn, en) % << '\n';
}
return ;
}
因为数据太大所以每次乘完都要取模,不然会溢出。
因为本来就给的是邻接矩阵,kruskal要多做一步处理转换成边表,速度大约是prim的一半
全连通图求最小生成树边权之积(邻接矩阵/prim/kruskal)的更多相关文章
- 最小生成树 链式前向星 Prim&Kruskal
Prim: Prim的思想是将任意节点作为根,再找出与之相邻的所有边(用一遍循环即可),再将新节点更新并以此节点作为根继续搜,维护一个数组:dis,作用为已用点到未用点的最短距离. 证明:Prim算法 ...
- hdu 3405 删掉某点后 求最小生成树
给出N个点的坐标 边的权值为两点间的距离 删掉其中某点 求最小生成树的权值和 要求这权值最小 因为最多50个点 所以具体是删哪个点 用枚举假如有4个点 就要求4次最小生成树 分别是2 3 4 | 1 ...
- 【2018 ICPC亚洲区域赛徐州站 A】Rikka with Minimum Spanning Trees(求最小生成树个数与总权值的乘积)
Hello everyone! I am your old friend Rikka. Welcome to Xuzhou. This is the first problem, which is a ...
- Prim算法和Kruskal算法求最小生成树
Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...
- prime算法求最小生成树(畅通工程再续)
连着做了四道畅通工程的题,其实都是一个套路,转化为可以求最小生成树的形式求最小生成树即可 这道题需要注意: 1:因为满足路的长度在10到1000之间才能建路,所以不满足条件的路径长度可以初始化为无穷 ...
- Kruskal和Prim算法求最小生成树
Kruskal算法求最小生成树 测试数据: 5 6 0 1 5 0 2 3 1 2 4 2 4 2 2 3 1 1 4 1 输出: 2 3 1 1 4 1 2 4 2 0 2 3 思路:在保证不产生回 ...
- 克鲁斯卡尔(Kruskal)算法求最小生成树
/* *Kruskal算法求MST */ #include <iostream> #include <cstdio> #include <cstring> #inc ...
- poj 2349 求最小生成树里面第m长的边
题目链接:https://vjudge.net/problem/POJ-2349 题意: 题目就是要我们找到一个最小的值D,把图里面所有大于D的边去掉之后剩余的连通分支的数量为S.这个就是找这个图里面 ...
- NYOJ 1875 畅通工程再续 (无节点间距离求最小生成树)
Description 相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题 ...
随机推荐
- 驱动之LCD的介绍与应用20170209
本文主要介绍的是LCD的介绍与应用,直接看个人笔记即可:
- HDU 4584 splay
Shaolin Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
- jsp 的 3 个编译指令
JSP 的编译指令是通知 JSP 引擎的消息,它不直接生成输出. 常见的编译指令有如下三个: 1.page:该指令是针对当前页面的指令 2.include:用于指定包含另一个页面 3.taglib:用 ...
- Python基础之面向对象(进阶篇)
面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实 ...
- mysql 在linux服务器恢复数据表方法记录
在本地搭建测试环境录入的数据放到线上测试,备份了数据表为一个.sql文件, 在服务器上登录mysql执行 source (如:source exposition_exposition.sql) 文件路 ...
- Cochran’s Q Test
sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...
- 前端PHP入门-028-文件操作-掌握级别
作为刚入门我们员经常会干的意见事情是ctrl+c和ctrl+v,鼠标右键删除文件.会control+c(或右键)复制.粘贴文件以及新建文件,还可以设置文件的是否为只读文件等等 可不可以写入修改配置文件 ...
- OpenCV---圆检测
推文:Opencv2.4.9源码分析——HoughCircles 霍夫圆检测 加载一幅图像并对其模糊化以降噪 对模糊化后的图像执行霍夫圆变换 . 在窗体中显示检测到的圆. def detect_cir ...
- mysql \G
mysql 命令区分大小写.ego (\G) Send command to mysql server, display result vertically. go (\g) ...
- JavaScript之RegExp
分为字面量和RegExp构造函数 1.正则表达式的匹配模式支持3个标志 g:表示全局模式,模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止 i:表示不区分大小写模式,即在确定匹配项时忽略模式 ...