zoukankan      html  css  js  c++  java
  • POJ1251 Jungle Roads【最小生成树】

    题意:

    首先给你一个图,需要你求出最小生成树,首先输入n个节点,用大写字母表示各节点,接着说有几个点和它相连,然后给出节点与节点之间的权值。
    拿第二个样例举例:比如有3个节点,然后接下来有3-1行表示了边的情况,拿第一行来说:
    A 2 B 10 C 40
    表示A有2个邻点,B和C,AB权值是10,AC权值是40。

    思路:

    直接套prime算法模板和kuskal算法模板,然后处理下数据就可以了。

    代码:

    prime:

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    using namespace std;
    const int maxn=30;
    const int inf=0x3f3f3f3f;
    int road[maxn][maxn],dis[maxn];
    bool vis[maxn];
    int n;
    
    void prim()
    {
        int minn, v;
        for(int i = 0; i < n; i++)
        {
            dis[i] = road[0][i];
            vis[i] = false;
        }
        for(int i = 1; i <= n; i++)//包括第一个点在内,一共要纳入n个点
        {
            minn = inf;
            for(int j = 0; j < n; j++)//每次找出未纳入顶点集与已知顶点集构成的权值最小的一条边
            {
                if(!vis[j] && minn > dis[j])
                {
                    v = j;
                    minn = dis[j];
                }
            }
            vis[v] = true;//把该顶点纳入已知集合
            for(int j = 0; j < n; j++)//更新与未纳入集合中的顶点的边的最小权值
            {
                if(!vis[j] && dis[j] > road[v][j])
                    dis[j] = road[v][j];
            }
        }
        for(int i = 1; i < n; i++)
            dis[0] += dis[i];
        cout << dis[0] << endl;
    }
    
    int main()
    {
        int m,w;
        char a[5],b[5];
        while(cin>>n,n)
        {
             memset(road,60,sizeof(road));
             for(int i=0;i<n;i++)
                road[i][i]=0;
             for(int i=1;i<n;i++)
             {
                 scanf("%s%d",a,&m);
                 for(int j=0;j<m;j++)
                 {
                     scanf("%s%d",b,&w);
                     road[a[0]-'A'][b[0]-'A']=road[b[0]-'A'][a[0]-'A']=w;
                 }
             }
             prim();
        }
        return 0;
    }
    View Code

    kruskal:

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int p[30];
    
    struct node
    {
        int villagea;
        int villageb;
        int distance;
    }roads[80];
    
    bool cmp(node a, node b)
    {
        return a.distance < b.distance;
    }
    
    int kruskal(int x)
    {
        return  p[x] == x ? x : p[x] = kruskal(p[x]);
    }
    
    int main()
    {
        int n, k, distance, number, ans;
        char start_village, end_village;
        while(cin >> n, n)
        {
            ans = k = 0;
            for(int i = 0; i < 27; i++)
                p[i] = i;
            for(int i = 0; i < n- 1; i++)
            {
                cin >> start_village >> number;
                for(int j = 0; j < number; j++, k++)
                {
                    cin >> end_village >> distance;
                    roads[k].villagea = start_village - 'A';
                    roads[k].villageb = end_village - 'A';
                    roads[k].distance = distance;
                }
            }
            sort(roads, roads + k, cmp);
            for(int i = 0; i < k; i++)
            {
                int x = kruskal(roads[i].villagea);
                int y = kruskal(roads[i].villageb);
                if(x != y)
                {
                    ans = ans + roads[i].distance;
                    p[y] = x;
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Linux系统模拟端口开放程序port 软件的基本使用
    Docker19.03.13离线安装-Docker根目录-Docker常用操作--NVIDIA Docker
    springboot项目启动与停止命令
    两种设备选型的主要性能指标
    docker nginx配置
    使用shell+java 抓取NHK广播
    小程序的测试方法
    adb logcat 查看Android APP日志
    IE11判断是否全是中文的时候无效写法
    C#控制器微信通过encryptedData,iv,Code获取用户信息
  • 原文地址:https://www.cnblogs.com/darklights/p/7635286.html
Copyright © 2011-2022 走看看