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


    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 - 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
    ", 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
    ", 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
    ", 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("
    ");
    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
  • 相关阅读:
    结对编程
    个人项目(JUnit单元测试)
    我的第一个GitHub仓库
    Visual Studio 创建C++或C#Windows程序
    字符串操作
    练习数值计算
    Hello World
    ceph部署出现错误及解决
    asp.net mvc 用Redis实现分布式集群共享Session。
    Unable to load DLL 'rasapi32.dll': 动态链接库(DLL)初始化例程失败。
  • 原文地址:https://www.cnblogs.com/zhangwanying/p/9431761.html
Copyright © 2020-2023  润新知