全连通图求最小生成树边权之积(邻接矩阵/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 相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题 ...
随机推荐
- 【bzoj3567】江南乐
Portal -->bzoj3567 Solution 今天开始啃博弈论了qwq 先mark一篇很棒的博客Portal -->博弈论学习资料 稍微总结一下两个自己容易混 ...
- 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现
一.客户端/服务器架构(C/S架构) 即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...
- 手脱ASPack v2.12变形壳2
1.PEID载入 ASPack v2.12 2.载入OD,跟之前帖子的入口特征相同,都是一个pushad,但是请不要怀疑这是同一个壳,绝对不是,pushad下一行ESP定律下硬件断点,然后shift+ ...
- JAVA类与对象---实例变量与类变量的区别,实例方法和类方法的区别
实例变量 实例变量声明在一个类中,但在方法.构造方法和语句块之外: 当一个对象被实例化之后,每个实例变量的值就跟着确定: 实例变量在对象创建的时候创建,在对象被销毁的时候销毁: 实例变量的值应该至少被 ...
- LightOJ 1088 - Points in Segments 二分
http://www.lightoj.com/volume_showproblem.php?problem=1088 题意:给出N个点,Q个查询,问在区间内的点数有多少个. 思路:直接在线二分,注意边 ...
- Material Design 之 TabLayout 使用
记录 (非常详细的 TabLayout用法), 学习 http://www.jianshu.com/p/13f334eb16ce
- 重构改善既有代码设计--重构手法05:Introduce Explaining Variable (引入解释性变量)
发现:你有一个复杂的表达式. 解决:将该复杂的表达式(或其中的部分)的结果放进一个临时变量,并以此变量名称来解释表达式用途. //重构前 if((platform.toUpperCase().in ...
- Tomcat处理一个http请求的过程
假设来自客户的请求为: http://localhost:8080/wsota/wsota_index.jsp 1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Con ...
- JQuery 中三十一种选择器的应用
选择器(selector)是CSS中很重要的概念,所有HTML语言中的标记都是通过不同的CSS选择器进行控制的.用户只需要通过选择器对不同的HTML标签进行控制,并赋予各种样式声明,即可实现各种效果. ...
- 20155117 王震宇 2006-2007-2 《Java程序设计》第三周学习总结
20155117 王震宇 2006-2007-2 <Java程序设计>第三周学习总结 教材学习内容总结 在JAVA程序编写中,常常要用到对象(Object),要产生对象首先要定义类(Cla ...