【解题报告】pku数算mooc 第8周 图 兔子与星空(poj 5442)
2017-11-22 19:13
375 查看
描述
很久很久以前,森林里住着一群兔子。兔子们无聊的时候就喜欢研究星座。如图所示,天空中已经有了n颗星星,其中有些星星有边相连。兔子们希望删除掉一些边,然后使得保留下的边仍能是n颗星星连通。他们希望计算,保留的边的权值之和最小是多少?
兔子与星空示意图
输入
第一行只包含一个表示星星个数的数n,n不大于26,并且这n个星星是由大写字母表里的前n个字母表示。接下来的n-1行是由字母表的前n-1个字母开头。最后一个星星表示的字母不用输入。对于每一行,以每个星星表示的字母开头,然后后面跟着一个数字,表示有多少条边可以从这个星星到后面字母表中的星星。如果k是大于0,表示该行后面会表示k条边的k个数据。每条边的数据是由表示连接到另一端星星的字母和该边的权值组成。权值是正整数的并且小于100。该行的所有数据字段分隔单一空白。该星星网络将始终连接所有的星星。该星星网络将永远不会超过75条边。没有任何一个星星会有超过15条的边连接到其他星星(之前或之后的字母)。在下面的示例输入,数据是与上面的图相一致的。
输出
输出是一个整数,表示最小的权值和
样例输入
9
A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
样例输出
216
原题链接:http://dsalgo.openjudge.cn/huawen08/2/
解题思路:
这是一个最小生成树问题,即用最小的总权值使得图中所有的节点连通。
按题目给出的条件来说的话,这个星空图是属于稀疏图,因此用Kruskal算法是比较好的,给出的代码也是使用Kruskal算法。
保存图中各边的信息的话,由于题目最后只求最小总权值,我自我开发了一种
当然啦其实就用邻接矩阵就挺好的,也完全ok。由于要做等价类归并,所以还要写并查算法的ParentTreeNode,ParentTree什么的一堆东西。
(所以我发现用prim算法写的东西要少很多···)
以下代码:
转载请注明原文链接。
想要浏览更多的学习内容可以看看博主更多其他的博文哦~
http://blog.csdn.net/weixin_38062864
很久很久以前,森林里住着一群兔子。兔子们无聊的时候就喜欢研究星座。如图所示,天空中已经有了n颗星星,其中有些星星有边相连。兔子们希望删除掉一些边,然后使得保留下的边仍能是n颗星星连通。他们希望计算,保留的边的权值之和最小是多少?
兔子与星空示意图
输入
第一行只包含一个表示星星个数的数n,n不大于26,并且这n个星星是由大写字母表里的前n个字母表示。接下来的n-1行是由字母表的前n-1个字母开头。最后一个星星表示的字母不用输入。对于每一行,以每个星星表示的字母开头,然后后面跟着一个数字,表示有多少条边可以从这个星星到后面字母表中的星星。如果k是大于0,表示该行后面会表示k条边的k个数据。每条边的数据是由表示连接到另一端星星的字母和该边的权值组成。权值是正整数的并且小于100。该行的所有数据字段分隔单一空白。该星星网络将始终连接所有的星星。该星星网络将永远不会超过75条边。没有任何一个星星会有超过15条的边连接到其他星星(之前或之后的字母)。在下面的示例输入,数据是与上面的图相一致的。
输出
输出是一个整数,表示最小的权值和
样例输入
9
A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
样例输出
216
原题链接:http://dsalgo.openjudge.cn/huawen08/2/
解题思路:
这是一个最小生成树问题,即用最小的总权值使得图中所有的节点连通。
按题目给出的条件来说的话,这个星空图是属于稀疏图,因此用Kruskal算法是比较好的,给出的代码也是使用Kruskal算法。
保存图中各边的信息的话,由于题目最后只求最小总权值,我自我开发了一种
multimap <int,pair<char,char>>的表示方法,因为其实每条边用完就不需要再用了。算是开发一种思路吧,注意要使用multimap因为边的权值可能相等。
当然啦其实就用邻接矩阵就挺好的,也完全ok。由于要做等价类归并,所以还要写并查算法的ParentTreeNode,ParentTree什么的一堆东西。
(所以我发现用prim算法写的东西要少很多···)
以下代码:
#include<iostream> #include<map> #include<string> using namespace std; //通过map保存各条边的数据... multimap<int, pair<char, char> > itoc; int leftn;//记录是否归并成了一个等价类 //本题星空图属于稀疏图,采用kruskal算法, //需要进行等价类的归并,采用父指针表示的并查算法 class partreenode { public: int v; partreenode * parent=NULL; }; class partree { public: partreenode * array; int size; partree(const int Size) //构造 { size = Size; array = new partreenode[size]; for (int i = 0; i < size; ++i) array[i].v = i; //0对应A,1对应B这样的形式保持同构 } partreenode * Find(partreenode *node) { partreenode* pointer = node; while (pointer->parent != NULL) pointer = pointer->parent; return pointer; } void Union(int i, int j) { partreenode *pi = Find(&array[i]); partreenode *pj = Find(&array[j]); if (pi != pj) { pj->parent = pi; } }//本题中都采用的简陋的函数实现,用不到的就没写- - bool Different(int i, int j) { partreenode *pi = Find(&array[i]); partreenode *pj = Find(&array[j]); return pi != pj; } }; int main() { int n; cin >> n; leftn = n; partree tree(n);//归并用的等价类 for (int i = 0; i < n-1; i++) { char t; cin >> t; int en; cin >> en; char te; int len; for (int j = 0; j < en; ++j) { cin >> te; cin >> len; //输入各边- -map怎么用忘得差不多了,可能不用写成这么复杂的形式吧 itoc.insert(pair<int,pair<char, char>>(len,pair<char, char>(t, te))); } } //下面开始真正做归并0.0 int ans = 0; //记录权值结果 while (leftn > 1) //等价类只剩一个的时候结束 { //itoc中按权值从小到大存储了各各边 multimap<int, pair<char, char> >::iterator it = itoc.begin(); int s1, s2 = 0; while (it != itoc.end()) { s1 = it->second.first - 65; s2 = it->second.second - 65; if (tree.Different(s1, s2)) //s1 s2不在同一等价类,则做归并 { tree.Union(s1, s2); --leftn; ans += it->first; //加入一条边,只问权值,所以只记录权值和 } ++it;//不满足条件或操作完成则直接进入下一条边 } } cout << ans; //system("pause"); return 0; }
转载请注明原文链接。
想要浏览更多的学习内容可以看看博主更多其他的博文哦~
http://blog.csdn.net/weixin_38062864
相关文章推荐
- 【解题报告】pku数算mooc 第8周 图 我爱北大(poj 4083)
- 【解题报告】poj openjudge 拼写检查 pku数算mooc 检索
- POJ 1001Exponentiation解题报告——求高精度幂——【PKU ACM】
- 单调队列 - 兼 ACM PKU POJ 3250 及 2823 解题报告
- POJ 1002求487-3279解题报告——【PKU ACM】
- 有向图的汇点 -- 兼 ACM PKU POJ 2186 ( Popular Cows ) 解题报告
- POJ 1003求Hangover解题报告——【PKU ACM】
- PKU POJ 3630解题报告(trie树)
- POJ 1004Financial Management解题报告——【PKU ACM】
- ACM PKU POJ 1112 解题报告
- ACM PKU POJ 1740 解题报告 -- 男人八题之四
- POJ 1005I Think I Need a Houseboat解题报告——【PKU ACM】
- PKU POJ 1611解题报告(并查集)
- POJ 1006Biorhythms解题报告——生理周期——【PKU ACM】
- PKU POJ 2524 解题报告(并查集)
- POJ 1007DNA Sorting解题报告——【PKU ACM】
- 整数分解和划分 - 兼 ACM PKU POJ 1221 解题报告
- 单调队列 - 兼 ACM PKU POJ 3250 及 2823 解题报告 [转]
- poj_2389_Bull Math_解题报告
- poj解题报告——1269