[kuangbin]专题六 最小生成树 题解+总结

kuangbin专题链接:https://vjudge.net/article/752

kuangbin专题十二 基础DP1 题解+总结:https://www.cnblogs.com/RioTian/p/13110438.html

最小生成算法 介绍模板

总结:

文章目录

1.Jungle Roads

原题链接:传送门

题意:

​ N个顶点的无向图,给你每条边的长度,要你求该图的最小生成树.其中每个点用大写字母A-Z表示.

思路:

​ 直接kruskal模板即可,转换输入格式.注意输入中的边没有重复边,所以无需判重.

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=30;
const int maxm=100+10;
 
struct Edge
{
    int u,v,dist;
    Edge(){}
    Edge(int u,int v,int d):u(u),v(v),dist(d){}
    bool operator<(const Edge &rhs)const
    {
        return dist<rhs.dist;
    }
};
 
struct Kruskal
{
    int n,m;
    Edge edges[maxm];
    int fa[maxn];
    int findset(int x){ return fa[x]==-1?x:fa[x]=findset(fa[x]); }
 
    void init(int n)
    {
        this->n=n;
        m=0;
        memset(fa,-1,sizeof(fa));
    }
 
    void AddEdge(int u,int v,int dist)
    {
        edges[m++]=Edge(u,v,dist);
    }
 
    int kruskal()
    {
        int sum=0,cnt=0;
        sort(edges,edges+m);
 
        for(int i=0;i<m;i++)
        {
            int u=edges[i].u, v=edges[i].v;
            if(findset(u) != findset(v))
            {
                sum +=edges[i].dist;
                fa[findset(u)] = findset(v);
                if(++cnt>=n-1) return sum;
            }
        }
        return -1;
    }
}KK;
 
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        KK.init(n);
        for(int i=0;i<n-1;i++)
        {
            char s1[10],s2[10];
            int k,v,d;
            scanf("%s%d",s1,&k);
            while(k--)
            {
                scanf("%s%d",s2,&d);
                v=s2[0]-'A';
                KK.AddEdge(i,v,d);
            }
        }
        printf("%d\n",KK.kruskal());
    }
    return 0;
}

Networking

原题链接:传送门

思路:

  1. 完完全全的模板题,按照最小生成树的思想写代码即可。

prim 算法

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ms(a,b) memset(a,b,sizeof a);
const int N = 55;
int n, m;
int g[N][N], d[N];
bool book[N];

int prime() {
    ms(d, 0x3f); ms(book, false);
    int ans = 0;
    //有点类似最短路的dijstra算法
    for (int i = 0; i < n; ++i) {
        int t = -1;
        for (int j = 1; j <= n; ++j) {
            if (!book[j] && (t == -1 || d[t] > d[j])) t = j;
        }
        book[t] = true;//加入集合
        if (i) ans += d[t];//代表不是第一个点	
        //改变其他点到该集合的距离 
        for (int j = 1; j <= n; ++j)d[j] = min(d[j], g[t][j]);
    }
    return ans;
}

int main() {
    //freopen("in.txt", "r", stdin);
    while (cin >> n && n) {
        cin >> m;
        //if (m == 0) { cout << 0 << endl; continue; }
        ms(g, 0x3f);
        int u, v, w;
        for (int i = 1; i <= m; ++i) {
            cin >> u >> v >> w;
            g[v][u] = g[u][v] = min(g[v][u], w);//重边,选择最小值
        }
        cout << prime() << endl;
    }
    return 0;
}

kruskal算法

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ms(a,b) memset(a,b,sizeof a);
const int maxn = 200 + 55;
const int maxm = 1e5 + 5;
struct edge {
    int from, to;
    int cost;
}b[maxm];
int n, m;
int f[maxn];

bool cmp(edge a, edge b) {
    return a.cost < b.cost;
}

int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }

int kruskal() {
    int u, v;
    int ans = 0, total = 0;
    for (int i = 1; i <= m; ++i) {
        u = find(b[i].from);
        v = find(b[i].to);
        if (u != v) {
            ans += b[i].cost;
            f[u] = v;
            ++total;
            if (total == n - 1)
                return ans;
        }
    }
    return 0;
}

int main() {
    //freopen("in.txt", "r", stdin);
    int u, v, w;
    while (cin >> n && n) {
        cin >> m;
        for (int i = 0; i <= n; ++i)f[i] = i;
        for (int i = 1; i <= m; ++i) {
            cin >> b[i].from >> b[i].to >> b[i].cost;
        }
        sort(b + 1, b + 1 + m,cmp);
        cout << kruskal() << endl;
    }
    return 0;
}

3.Constructing Roads

原题链接:传送门

思路:

4.Agri-Net

原题链接:传送门

思路:

5.The Unique MST

原题链接:传送门

思路:

6.Highways

原题链接:传送门

思路:

7.Arctic Network

原题链接:传送门

思路:

8.Building a Space Station

原题链接:传送门

思路:

9.还是畅通工程

原题链接:传送门

思路:

10.畅通工程再续

原题链接:传送门

思路:

猜你喜欢

转载自www.cnblogs.com/RioTian/p/13380764.html