• Light OJ 1041


    题目链接

    http://www.lightoj.com/volume_showproblem.php?problem=1041

    题目大意

    有m个关系, 每个关系是两个城市相距的距离,求把这些城市全部连接起来的最小距离。
    

    解题思路

    典型的最小生成树
    

    代码如下

    kruskal算法
    
    #include<bits/stdc++.h>
    using namespace std;
     
    const int N = 57;
    const int INF = 0x3f3f3f3f;
     
    struct edge
    {
        int u, v, cost;
        edge() = default;
        edge(int x, int y, int z)
        {
            u = x, v = y, cost = z;
        }
    };
    edge arr[N];
     
     
    map<string, int>mp;
    set<string> st;
     
    int par[N];
    int Rank[N];
     
     
    void init(int n)
    {
        for(int i=1; i<=n; ++ i)
            par[i] = i, Rank[i] = 0;
    }
     
    int Find(int x)
    {
        if(x == par[x])
            return x;
        return par[x] = Find(par[x]);
    }
     
    void unite(int x, int y)
    {
        x = Find(x);
        y = Find(y);
        if(x == y)
            return ;
        if(Rank[x] < Rank[y])
            par[x] = y;
        else
        {
            par[y] = x;
            if(Rank[x] == Rank[y])
                Rank[x] ++;
        }
    }
     
    bool same(int x, int y)
    {
        if(Find(x) == Find(y))
            return true;
        return false;
    }
    bool cmp(const edge &a, const edge &b)
    {
        return a.cost < b.cost;
    }
     
    int kruskal(int e, int v)
    {
        sort(arr, arr+e, cmp);
        init(v);
        int res = 0;
        for(int i=0; i<e; ++ i)
        {
            edge s = arr[i];
            if(same(s.u, s.v) == false)
            {
                unite(s.u, s.v);
                res += s.cost;
            }
        }
        return res;
    }
     
    void solve(int cases)
    {
        int n;
        scanf("%d", &n);
     
        string a, b;
        int c;
     
        int s = 1;
        mp.clear(), st.clear();
        for(int i=0; i<n; ++ i)
        {
            cin >> a >> b >> c;
            if(st.count(a) == 0)
            {
                st.insert(a);
                mp[a] = s ++;
            }
            if(st.count(b) == 0)
            {
                st.insert(b);
                mp[b] = s ++;
            }
            arr[i] = edge(mp[a], mp[b], c);
        }
     
        int res = kruskal(n, s-1);
        int is = 0;
        for(int i=1; i<s; ++ i)
            if(par[i] == i)
            is ++;
        if(is > 1)
            printf("Case %d: Impossible
    ", cases);
        else
            printf("Case %d: %d
    ", cases, res);
    }
     
    int main()
    {
        int t;
        scanf("%d", &t);
        for(int i=1; i<=t; ++ i)
            solve(i);
        return 0;
    }
    
  • 相关阅读:
    反汇编测试
    《Unix/Linux系统编程》第五章学习笔记
    Linux学习笔记
    团队作业三
    缓冲区溢出
    ch6信号学习笔记
    ch5(定时器和时钟)学习笔记
    团队作业(四)
    团队作业(三)
    ch4学习笔记
  • 原文地址:https://www.cnblogs.com/aiterator/p/6494300.html
Copyright © 2020-2023  润新知