一、mst 沒有堆優化的prim算法node
原題連接: http://hihocoder.com/problemset/problem/1097 ios
1 //原題連接: http://hihocoder.com/problemset/problem/1097 2 3 #include <iostream> 4 #include <cstdio> 5 #include <set> 6 #include <cstring> 7 #include <climits> 8 using namespace std; 9 10 int gra[1010][1010]; 11 int vis[1010]; 12 int min_dis[1010]; //圖上的每一個節點到mst的距離 13 14 int main() { 15 memset(gra, 0x7f, sizeof(gra)); 16 memset(vis, 0, sizeof(vis)); 17 memset(min_dis, 0x7f, sizeof(min_dis)); 18 int n; 19 scanf("%d", &n); 20 for (int i = 0; i < n; ++i) { 21 for (int j = 0; j < n; ++j) { 22 scanf("%d", &gra[i][j]); 23 } 24 } 25 //初始化 26 vis[0] = 1; 27 int left = n - 1; 28 min_dis[0] = 0; //第0個節點就是樹開始計算的第一個結點 29 for (int i = 1; i < n; ++i) { 30 min_dis[i] = gra[0][i]; 31 } 32 33 int min_cost = 0; 34 35 while (left) { 36 int vertex = 1, minn_dis = INT_MAX; 37 //從沒有訪問過的全部節點中找出距離樹的距離最小的一個. 38 for (int i = 0; i < n; ++i) { 39 if (!vis[i] && min_dis[i] < minn_dis) { 40 vertex = i, minn_dis = min_dis[i]; 41 } 42 } 43 vis[vertex] = true; 44 min_cost += minn_dis; 45 left--; 46 //printf("%d : vertex: %d; minn_dis[%d] \n", n - left - 1, vertex, minn_dis); 47 48 //把找到的新的點加到mst中,而後更新每一個沒有訪問過的結點到mst的距離 49 for (int i = 0; i < n; ++i) { 50 if (!vis[i] && min_dis[i] > gra[vertex][i]) { 51 min_dis[i] = gra[vertex][i]; 52 } 53 } 54 } 55 printf("%d\n", min_cost); 56 return 0; 57 }
二、並查集優化的kruskal算法算法
原題連接:https://hihocoder.com/problemset/problem/1098ide
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 7 using namespace std; 8 9 int u[1000100], v[1000100], w[1000100], r[1000100]; 10 int fa[100020]; 11 12 bool cmp (const int x, const int y) { 13 return w[x] < w[y]; 14 } 15 16 void initSet(const int n) { 17 for (int i = 0; i < n; ++i) { 18 fa[i] = i; 19 } 20 } 21 22 int find(int x) { 23 return x == fa[x] ? x : fa[x] = find(fa[x]); 24 } 25 26 int main() { 27 int n, m; 28 scanf("%d %d", &n, &m); 29 30 initSet(n); //初始化並查集 31 for (int i = 0; i < m; ++i) { 32 scanf("%d %d %d", &u[i], &v[i], &w[i]); 33 r[i] = i; //初始化邊的序號 34 } 35 sort(r, r + m, cmp); //把邊按照邊的權重間接排序 36 37 /* 38 //打印sort以後的值 39 for(int i = 0; i < m; ++i) { 40 int idx = r[i]; 41 printf("%d %d %d\n", u[idx], v[idx], w[idx]); 42 } 43 */ 44 45 int ans = 0; 46 int cnt = 0; 47 for(int i = 0; i < m; ++i) { 48 int e = r[i]; 49 int x = find(u[e]), y = find(v[e]); //找出當前兩個端點所在的集合編號 50 if (x != y) { //不在同一個集合則合併 51 ans += w[e]; 52 fa[x] = y; 53 cnt++; 54 if (cnt == n-1) { 55 break; 56 } 57 } 58 } 59 printf("%d\n", ans); 60 return 0; 61 }
三、求最短路的算法優化
(1)floyed (O(N^3))spa
(2)Dijkstra(O(nlogn))堆優化以後的算法code
例題:https://www.luogu.org/problemnew/show/P3366blog
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <queue> 5 6 using namespace std; 7 int graph[1005][1005]; 8 int n, m; 9 int res = 1; 10 struct HeapNode { 11 int u, d; 12 HeapNode(int node, int weight): u(node), d(weight) {} 13 bool operator<(const HeapNode& rhs) const { 14 return d > rhs.d; 15 } 16 }; 17 void dijkstra(int src) { 18 vector<int> dis(n, INT_MAX); 19 dis[0] = 0; 20 priority_queue<HeapNode> que; 21 que.push(HeapNode(src, 0)); 22 while (!que.empty()) { 23 HeapNode cur = que.top(); que.pop(); 24 int u = cur.u, d = cur.d; 25 if (dis[u] != d) {continue;} 26 for (int v = 0; v < n; ++v) { 27 if (graph[u][v] == -1) {continue;} 28 if (dis[u] + graph[u][v] < dis[v]) { 29 dis[v] = dis[u] + graph[u][v]; 30 que.push(HeapNode(v, dis[v])); 31 } 32 } 33 } 34 for (auto d : dis) { 35 printf("%d ", d); 36 } 37 printf("\n"); 38 39 } 40 int main(int argc, char *argv[]) { 41 cin >> n >> m; 42 memset(graph, -1, sizeof(graph)); 43 for (int k = 0; k < m; ++k) { 44 int u, v, w; 45 cin >> u >> v >> w; 46 graph[u-1][v-1] = w; 47 } 48 dijkstra(0); 49 }