【图论】基础算法实现笔记 (最小生成树和最短路)

1、mst 没有堆优化的prim算法

原题链接: http://hihocoder.com/problemset/problem/1097 

 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 }
View Code

 

2、并查集优化的kruskal算法

原题链接:https://hihocoder.com/problemset/problem/1098

 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 }
View Code

 

3、求最短路的算法

(1)floyed (O(N^3))

(2)Dijkstra(O(nlogn))堆优化之后的算法

例题:https://www.luogu.org/problemnew/show/P3366

 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 }
View Code

 

posted @ 2019-03-20 20:55  zhangwanying  阅读(193)  评论(0编辑  收藏  举报