18.11.20 图作业三则(Kruskal\Floyd\朱刘算法)

2023-11-20 18:11

本文主要是介绍18.11.20 图作业三则(Kruskal\Floyd\朱刘算法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

兔子与星空(10分)

题目内容:

很久很久以前,森林里住着一群兔子。兔子们无聊的时候就喜欢研究星座。如图所示,天空中已经有了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

 

时间限制:500ms内存限制:32000kb
 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <string>
 6 #include <math.h>
 7 #include <queue>
 8 #include <stdio.h>
 9 #include <string.h>
10 #include <vector>
11 #include <fstream>
12 #include <set>
13 #define  inf 999999;
14 
15 using namespace std;
16 int n, classp[27];
17 struct edge {
18     int x, y;
19     int val;
20 }all[500];
21 
22 struct finder {
23     bool operator()(edge a, edge b) { return a.val < b.val; }
24 }myfinder;
25 
26 void uni(int x, int y) {//classp[x]<classp[y]
27     int val = classp[y];
28     for (int i = 0; i < 26; i++)
29         if (classp[i] == val)
30             classp[i] = classp[x];
31 }
32 
33 void init() {
34     scanf("%d", &n);
35     for (int i = 0; i < 26; i++)
36         classp[i] = i;
37     int edgen = 0;
38     for (int i = 1; i <= n - 1; i++) {
39         char ch;
40         cin.ignore();
41         scanf("%c", &ch);
42         int j;
43         scanf("%d", &j);
44         for (int k = 1; k <= j; k++) {
45             char p; int val;
46             cin.ignore();
47             scanf("%c%d", &p, &val);
48             all[++edgen].x = ch - 'A';
49             all[edgen].y = p - 'A';
50             all[edgen].val = val;
51         }
52     }
53     sort(all + 1, all + edgen + 1,myfinder);
54     int sum = 0;
55     for(int i=1;i<=edgen;i++)
56         if (classp[all[i].x] != classp[all[i].y]) {
57             if (all[i].x < all[i].y)
58                 uni(all[i].x, all[i].y);
59             else
60                 uni(all[i].y, all[i].x);
61             sum += all[i].val;
62         }
63     printf("%d\n", sum);
64 }
65 
66 int main()
67 {
68     init();
69     return 0;
70 }
View Code

大概是裸MST

 

兔子与樱花(10分)

 

题目内容:

很久很久之前,森林里住着一群兔子。有一天,兔子们希望去赏樱花,但当他们到了上野公园门口却忘记了带地图。现在兔子们想求助于你来帮他们找到公园里的最短路。

 

输入格式:

输入分为三个部分。
第一个部分有P+1行(P<30),第一行为一个整数P,之后的P行表示上野公园的地点。
第二个部分有Q+1行(Q<50),第一行为一个整数Q,之后的Q行每行分别为两个字符串与一个整数,表示这两点有直线的道路,并显示二者之间的矩离(单位为米)。
第三个部分有R+1行(R<20),第一行为一个整数R,之后的R行每行为两个字符串,表示需要求的路线。

 

输出格式:

输出有R行,分别表示每个路线最短的走法。其中两个点之间,用->(矩离)->相隔。

 

输入样例:

6
Ginza
Sensouji
Shinjukugyoen
Uenokouen
Yoyogikouen
Meijishinguu
6
Ginza Sensouji 80
Shinjukugyoen Sensouji 40
Ginza Uenokouen 35
Uenokouen Shinjukugyoen 85
Sensouji Meijishinguu 60
Meijishinguu Yoyogikouen 35
2
Uenokouen Yoyogikouen
Meijishinguu Meijishinguu

 

输出样例:

Uenokouen->(35)->Ginza->(80)->Sensouji->(60)->Meijishinguu->(35)->Yoyogikouen
Meijishinguu

 

 

时间限制:500ms内存限制:32000kb
 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <string>
 6 #include <math.h>
 7 #include <queue>
 8 #include <stdio.h>
 9 #include <string.h>
10 #include <vector>
11 #include <fstream>
12 #include <set>
13 #define  inf 999999;
14 
15 using namespace std;
16 int adj[31][31], path[31][31];
17 int p, q, r;
18 string spot[31];
19 int dis[31][31];
20 
21 int find(string a) {
22     for (int i = 1; i <= p; i++)
23         if (a == spot[i])
24             return i;
25 }
26 
27 void getrout(int s1, int s2) {
28     if (s1 != s2)
29     {
30         while (1) {
31             cout << spot[s1] << "->(" << dis[s1][path[s1][s2]] << ")->";
32             if (path[s1][s2] == s2)break;
33             s1 = path[s1][s2];
34         }
35     }
36     cout << spot[s2] << endl;
37 }
38 
39 void dp() {
40     for(int l=0;l<p;l++)
41     for (int i = 1; i <= p; i++) 
42         for(int j=1;j<=p;j++)
43             for (int k = 1; k <= p; k++) {
44                 if (adj[i][k] + adj[k][j] < adj[i][j]) {
45                     adj[i][j] = adj[i][k] + adj[k][j];
46                     path[i][j] = path[i][k];
47                 }
48             }
49 }
50 
51 void init() {
52     scanf("%d", &p);
53     for(int i=1;i<=p;i++)
54         for (int j = 1; j <= p; j++) {
55             if (i == j) {
56                 adj[i][j] = 0;
57                 path[i][j] = i;
58             }
59             else
60             {
61                 adj[i][j] = inf;
62                 path[i][j] = -1;
63             }
64         }
65     for (int i = 1; i <= p; i++)
66         cin >> spot[i];
67     scanf("%d", &q);
68     for (int i = 1; i <= q; i++)
69     {
70         string a, b;
71         cin >> a >> b;
72         int s1 = find(a), s2 = find(b);
73         scanf("%d", &dis[s1][s2]);
74         dis[s2][s1] = dis[s1][s2];
75         adj[s1][s2] = dis[s1][s2];
76         adj[s2][s1] = dis[s1][s2];
77         path[s1][s2] = s2;
78         path[s2][s1] = s1;
79     }
80     dp();
81     scanf("%d", &r);
82     for (int i = 1; i <= r; i++) {
83         string a, b;
84         cin >> a >> b;
85         getrout(find(a), find(b));
86     }
87 }
88 
89 int main()
90 {
91     init();
92     return 0;
93 }
View Code

模糊记得难点在输出?

这道考点好像是Floyd,也是裸的

吐槽一下上面两道题的机翻

也许还是日文题……?风格也很清新……

有点想去日本玩呜呜呜

地震之后(10分)

题目内容:

 2008年地震之后,坚强县受灾严重,该县通信线路也收到了致命的打击,县总部为了能够及时的向各村的发送消息,命令小强去解决一下这个问题。

  小强经过调查发现,为了能够快速的实现通信,当务之急是能够建立起一条从总部可以向各个村单向发送信息的通信系统。由于灾后情况紧急,不是每一个村之间都能够快速的建立起通信线路,只有有限的村比如村A和村B间可以建立单向的从A向B发送信息的通信线路,小强现在的问题就是要找出一个合适的方案,使从总部发送出的信息能够通到各村,而用的总的通信线路是最短的(毕竟情况危急,物质短缺)。

 

输入格式:

输入包括多组的测试数据。
对于每一组测试数据:
1、第一行包括两个整数N(1<=N<=100),M(M<<=10000),N表示通信网络中村子的数量,M表示在这些村子中,可以有M条通信线路建起来。
2、接下来N行,每行两个整数xi,yi,代表着这个村子的X轴,Y轴的坐标(xi,yi)
3、接下来M行,每行两个整数c1(1<=c1<=N),c2(1<=c2<=N),代表着从村c1到村c2可以建一个单向线路。

注:两村之间的直线段距离(通信线路长度),即为两点间的欧式距离。
县总部所在的村假设都在编号为1的村。
输入以文件终止为结束。

 

输出格式:

对于每一组的测试数据,输出完全的一行,值为最短的总长度,结果保留两位小数。
如果不能建立一个单向的临时网络,输出"NO".

 

输入样例:

4 6
3 6
4 6
3 4
7 20
1 2
1 3
2 3
3 4
3 1
3 2
4 3
0 0
1 0
1 1
1 2
1 3
4 1
2 3

 

输出样例:

19.49
NO

 

时间限制:500ms内存限制:32000kb
  1 #include <iostream>
  2 #include <string.h>
  3 #include <algorithm>
  4 #include <stack>
  5 #include <string>
  6 #include <math.h>
  7 #include <queue>
  8 #include <stdio.h>
  9 #include <string.h>
 10 #include <vector>
 11 #include <fstream>
 12 #include <set>
 13 #define maxn 101
 14 #define inf 0x7fffffff
 15 
 16 using namespace std;
 17 struct edge {
 18     int from, to;
 19     double val;
 20 };
 21 edge all[maxn * 100];
 22 int n, m;
 23 double in[maxn];
 24 int pre[maxn];
 25 int id[maxn];
 26 int vis[maxn];
 27 double px[maxn], py[maxn];
 28 int root;
 29 
 30 void zhuliu() {
 31     double ans = 0;
 32     while (1) {
 33         for (int i = 1; i <= n; i++)
 34             in[i] = inf;
 35         for (int i = 1; i <= m; i++) {
 36             int from = all[i].from, to = all[i].to;
 37             if (all[i].val < in[to] && from != to) {
 38                 in[to] = all[i].val;
 39                 pre[to] = from;
 40             }
 41         }
 42         for (int i = 1; i <= n; i++) {
 43             if (i == root)continue;
 44             if (in[i] == inf) {
 45                 printf("NO\n");
 46                 return;
 47             }
 48         }
 49         /*寻找环*/
 50         int cnt = 1;//缩点数目
 51         memset(id, -1, sizeof(id));
 52         memset(vis, -1, sizeof(vis));
 53         in[root] = 0;
 54         for (int i = 1; i <= n; i++) {
 55             ans += in[i];
 56             int v = i;
 57             while (vis[v] != i && id[v] == -1 && v != root) {
 58                 vis[v] = i;
 59                 v = pre[v];
 60             }
 61             if (v != root && id[v] == -1) {
 62                 for (int u = pre[v]; u != v; u = pre[u])
 63                     id[u] = cnt;
 64                 id[v] = cnt++;
 65             }
 66         }
 67         /*没有找到自环*/
 68         if (cnt == 1) {
 69             printf("%.2lf\n", ans);
 70             return;
 71         }
 72         /*找到不是自环的,重新给那些点标记*/
 73         for (int i = 1; i <= n; i++)
 74             if (id[i] == -1)id[i] = cnt++;
 75         for (int i = 1; i <= m; i++) {
 76             int to = all[i].to;
 77             all[i].from = id[all[i].from];
 78             all[i].to = id[all[i].to];
 79             if (all[i].from != all[i].to)
 80                 all[i].val -= in[to];
 81         }
 82         n = cnt-1;
 83         root = id[root];
 84     }
 85 }
 86 
 87 void init() {
 88     while (cin >> n >> m) {
 89         root = 1;
 90         for (int i = 1; i <= n; i++)
 91             scanf("%lf%lf", &px[i], &py[i]);
 92         for (int i = 1; i <= m; i++) {
 93             int x, y;
 94             scanf("%d%d", &x, &y);
 95             double l1 = px[x] - px[y], l2 = py[x] - py[y];
 96             all[i].from = x, all[i].to = y;
 97             all[i].val = sqrt(l1*l1 + l2 * l2);
 98         }
 99         zhuliu();
100     }
101 }
102 
103 int main()
104 {
105     init();
106     return 0;
107 }
View Code

是裸的朱刘算法(最小树形图)

暂时的理解(有点怕理解错在这里写一下)是:每次择出每个点作为入点时的最小边,并在将这些边算入答案后查看由这些边组成的图中有无环,如果有就缩点(因为他们可以相互连通),将缩点后的图重新进行上述操作,一遍一遍筛下来,图中不存在环的时候就能算出答案。算是有点贪心思想……?我其实也没有理解透彻-^-因为不考,非常功利地套了下模板随便糊弄完事。我来打脸了,考了,真是低估出卷人了

wa点

太弱鸡导致连改模板都漏掉了一些地方。因为我是以编号1为第一个元素的,所以cnt起始应该是1,第一遍写的时候没有把模板中的改掉。

 

当时做的时候就比较懒,算法很多都写得很不好,前两道完全没有考虑复杂度

第三题发现在课程内容之外就没有及时做(第一次十分天真地用了无向图MST算法……我真是个傻子……然后就没心思改了),现在po的时候发现前两道都忘了……以后还是做一道po一道吧

希望我的标题没写错(。

转载于:https://www.cnblogs.com/yalphait/p/9989327.html

这篇关于18.11.20 图作业三则(Kruskal\Floyd\朱刘算法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/396478

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

uva 10099(floyd变式)

题意: 有一个导游要带着一群旅客从一个城市到达另一个城市,每个城市之间有最大的旅客流量限制。 问最少几趟能将这些旅客从一个城市搞到另一个城市。 解析: 用floyd找出最小流量中的最大边,然后次数就是   ceil(总人数 / 最大承载量 - 1),-1的意思是导游每次也要在车上。 ps.老司机哭晕在厕所 代码: #include <iostream>#includ

uva 10048(floyd变式)

题意: 求两个点之间经过的路径中最大噪声最小的值。 解析: floyd的变式,每次取g[i][k] g[k][j]中的大边与当前边g[i][j]比较,取小。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#includ