搜索与图论模板

64 阅读1分钟

本文已参与[新人创作礼]活动,一起开启掘金创作者之路。

floyd算法 时间复杂度是 O(n3)O(n3), nn 表示点数 初始化: for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) if (i == j) d[i][j] = 0; else d[i][j] = INF;

// 算法结束后,d[a][b]表示a到b的最短距离 void floyd() { for (int k = 1; k <= n; k ++ ) for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } 朴素版prim算法 时间复杂度是 O(n2+m)O(n2+m), nn 表示点数,mm 表示边数 int n; // n表示点数 int g[N][N]; // 邻接矩阵,存储所有边 int dist[N]; // 存储其他点到当前最小生成树的距离 bool st[N]; // 存储每个点是否已经在生成树中

// 如果图不连通,则返回INF(值是0x3f3f3f3f), 否则返回最小生成树的树边权重之和 int prim() { memset(dist, 0x3f, sizeof dist);

int res = 0;
for (int i = 0; i < n; i ++ )
{
    int t = -1;
    for (int j = 1; j <= n; j ++ )
        if (!st[j] && (t == -1 || dist[t] > dist[j]))
            t = j;

    if (i && dist[t] == INF) return INF;

    if (i) res += dist[t];
    st[t] = true;

    for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], g[t][j]);
}

return res;

} Kruskal算法 时间复杂度是 O(mlogm)O(mlogm), nn 表示点数,mm 表示边数 int n, m; // n是点数,m是边数 int p[N]; // 并查集的父节点数组

struct Edge // 存储边 { int a, b, w;

bool operator< (const Edge &W)const
{
    return w < W.w;
}

}edges[M];

int find(int x) // 并查集核心操作 { if (p[x] != x) p[x] = find(p[x]); return p[x]; }

int kruskal() { sort(edges, edges + m);

for (int i = 1; i <= n; i ++ ) p[i] = i;    // 初始化并查集

int res = 0, cnt = 0;
for (int i = 0; i < m; i ++ )
{
    int a = edges[i].a, b = edges[i].b, w = edges[i].w;

    a = find(a), b = find(b);
    if (a != b)     // 如果两个连通块不连通,则将这两个连通块合并
    {
        p[a] = b;
        res += w;
        cnt ++ ;
    }
}

if (cnt < n - 1) return INF;
return res;

}

来自y总, y总算法教的非常的好,十分推荐。