所有边权均不相同的无向图最小生成树是唯一的证明_证明若无向连通图上各边权值均不相同,则该图的最小代价生成树一定是唯一的。-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 }
唉........
【原创】优先队列 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 }