所有边权均不相同的无向图最小生成树是唯一的证明_证明若无向连通图上各边权值均不相同,则该图的最小代价生成树一定是唯一的。-CSDN博客

7-1 校园最短路径

下图是校园地图,请创建地图模型,并基于该模型求出一教到其余各地的最短路径和长度。

输入样例:

14 14
ABCDEFGHIJKLMN
AB 1
AC 1
AD 3
BG 2
CE 1
DM 3
EF 1
FI 2
GJ 5
IL 3
JL 2
KL 2
KN 6
MN 5

输出样例:

dist[A][A]=0
A
dist[A][B]=1
A->B
dist[A][C]=1
A->C
dist[A][D]=3
A->D
dist[A][E]=2
A->C->E
dist[A][F]=3
A->C->E->F
dist[A][G]=3
A->B->G
dist[A][H]=256
H
dist[A][I]=5
A->C->E->F->I
dist[A][J]=8
A->B->G->J
dist[A][K]=10
A->C->E->F->I->L->K
dist[A][L]=8
A->C->E->F->I->L
dist[A][M]=6
A->D->M
dist[A][N]=11
A->D->M->N
 
 1 #include <iostream>
 2 #include<queue>
 3 #include<stack>
 4 #include<vector>
 5 #include<cstring>
 6 using namespace std;
 7 #define maxenum 100
 8 int dist[maxenum];
 9 char path[maxenum];
10 bool visited[maxenum];
11 typedef pair<int, char> p;
12 typedef struct edge {
13     char to;
14     int w;
15 }edge;
16 vector<edge>g[maxenum];
17 void init() {
18     for (int i = 0; i < 100; i++) {
19         dist[i] = 256;
20     }//数组赋初值memset还是不太会用,还是老老实实用这个方法吧o( ̄┰ ̄*)ゞ
21     memset(visited, false, sizeof(visited));//赋值用true和false
22     memset(path, -1, sizeof(path));
23 }
24 void dijkstra(char s) {
25     priority_queue<p, vector<p>, greater<p>>q;
26     q.push(p(0, s));
27     while (!q.empty()) {
28         p temp = q.top();
29         q.pop();
30         int u=temp.second;
31         if (visited[u])
32             continue;
33         visited[u] = 1;
34         edge uu;
35         for (int i = 0; i < g[u].size(); i++) {
36             uu = g[u][i];
37             if (!visited[uu.to] && dist[uu.to] > dist[u] + uu.w) {
38                 path[uu.to] = u;//记录前驱节点
39                 dist[uu.to] = dist[u] + uu.w;
40             }
41                 q.push(p(dist[uu.to], uu.to));
42         }
43     }
44 
45 }
46 void print(char s,char e) {
47     if (path[e] == s)
48         cout << s;
49     else
50         print( s, path[e]);
51     cout << "->" << e;
52     return;
53 }//递归输出路径
54 int main()
55 {
56     init();
57     int n, m;
58     cin >> n >> m;
59     string ss;
60     string u;
61     int w;
62     cin >> ss;
63     edge temp1,temp2;
64     for (int i=0; i < m; i++) {
65         cin >> u >> w;
66         temp1.to = u.at(1);
67         temp2.to = u.at(0);
68         temp1.w = w;
69         temp2.w = w;
70         g[u.at(0)].push_back(temp1);
71         g[u.at(1)].push_back(temp2);
72     }
73     char s = ss.at(0);
74     dist[s] = 0;
75     dijkstra(s);
76     for (size_t i = 0; i < ss.size(); i++) {//访问字符串里面的每个字符,在声明诸如字符数或者数组索引这样的长度变量时用size_t 是好的做法,size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数。
77         cout <<"dist"<<"["<<s<<"]"<< "[" << ss[i] << "]"<<"="<< dist[ss[i]]<<endl;
78         if (dist[ss[i]] != 0 && dist[ss[i]] != 256) {
79             print(s, ss[i]);
80         }
81         else
82             cout << ss[i];
83         cout << endl;
84     }
85 }
View Code

唉........

并查集详解(C/C++)_啊哈c 并查集-CSDN博客

【原创】优先队列 priority_queue 详解-CSDN博客 这个写的很好很清晰

7-2 最小生成树-kruskal算法

某地对偏远地区实行“村村通”工程,目标是使整个地区任何两个村落间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可)。现得到拟修建道路的费用,现请你编写程序,计算出全地区畅通需要的最低成本。

输入格式:

输入的第一行给出村庄数目N (1≤N≤20)和拟修建的道路数M

接下来的M行对应修建每条村庄间道路的成本,每行给出3个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本。

输出格式:

输出需修建的道路,按kruskal算法得到的顺序,输出每条路,每行输出一条道路,形式如:道路1编号,道路2编号,费用。(编号小的放前面,编号大的放后面,逗号为英文状态下的逗号)

输入样例:

4 6
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5

输出样例:

1,2,1
1,4,1
2,3,3
 1 // 18_zuixiaoshengchengshu.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
 2 //
 3 
 4 #include <iostream>
 5 #include<vector>
 6 #include<queue>
 7 using namespace std;
 8 #define maxn 100
 9 int n, m;
10 typedef struct edge {
11     int st;
12     int to;
13     int w;
14 }edge;
15 int parent[maxn];
16 int h[maxn];//树的高度
17 void init() {//初始化n个不相交集合
18     for (int i = 0; i < n; i++) {
19         parent[i] = i;
20         h[i] = 0;
21     }
22 }
23 int find(int a) {
24     int root = a;
25     while (parent[root] != root)
26         root = parent[root];
27     while (parent[a] != a) {//压缩路径
28         int temp = parent[a];
29         parent[a] = root;
30         a = temp;
31     }
32     return root;
33 }
34 void unionn(int a, int b) {
35     int roota = find(a);
36     int rootb = find(b);
37     if (h[roota] >h[rootb]) {//按秩合并
38         parent[rootb] = roota;
39     }
40     else if(h[roota] > h[rootb]){
41         parent[roota] = rootb;
42     }
43     else {
44         parent[rootb] = roota;
45         h[roota]++;
46     }
47 }
48 struct cmp {
49     bool operator()(edge a, edge b) {
50         return a.w > b.w;
51     }
52 };
53 priority_queue<edge, vector<edge>, cmp> q;
54 void kruskal() {
55     init();
56     int sum=0;
57     while (!q.empty()) {
58         int a = q.top().st;
59         int b = q.top().to;
60         int c = q.top().w;
61         q.pop();
62         if (find(a) != find(b)) {
63              sum += c;
64              cout << a << "," << b << "," << c << endl;
65              unionn(a, b);
66         }
67     }
68     return;
69 }
70 
71 int main()
72 {
73     cin >> n >> m;
74     int w, y, z;
75     edge temp1;
76     for (int i = 0; i < m; i++) {
77         cin >> w >> y >> z;
78         temp1.st = w;
79         temp1.to = y;
80         temp1.w = z;
81         q.push(temp1);
82     }
83     kruskal();
84 }
View Code

 

 
posted on 2023-12-30 10:47  fmos  阅读(30)  评论(0编辑  收藏  举报