题目链接>>>

题目大意:

给出n个城市,接下来n行每一行对应该城市所能连接的城市的个数,城市的编号以及花费,现在求能连通整个城市所需要的最小花费。

解题分析:

最小生成树模板题,下面用的是kruscal算法。

//Kruscal算法采用的是"加边"的想法
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
];
int n, m, k;

struct line
{
    int x,y,c;
}edge[];

bool cmp(line a, line b)
{
    return a.c < b.c;
}

int find(int x)
{
    int r = x;
    while (father[r] != r)r = father[r];
    int i = x, j;
    while (father[i] != r)
    {
        j = father[i];
        father[i] = r;
        i = j;
    }
    return r;
}

void kruskal()
{
    int i, j;
    ;
    sort(edge, edge + k, cmp);
    ; i <= k; i++)        //按从小到大的顺序将所有不会构成环的边加入当前边集
    {
        int f1 = find(edge[i].x);
        int f2 = find(edge[i].y);
        if (f1 != f2)
        {
            father[f2] = f1;
            sum += edge[i].c;
        }
    }
    printf("%lld\n", sum);
}

int main()
{
    ,a2;
    char str1, str2;
    ,n)
    {
        k = ;
        memset(edge, , sizeof(edge));                //记得每次都要清空bian数组
        ; i < n; i++)
        {
            getchar();
            scanf("%c%d", &str1, &m);
            ; j <= m; j++)
            {
                getchar();
                scanf("%c%d", &str2, &a2);
                edge[k].x = str1 - ; //第一个村庄的编号从1开始
                edge[k].y = str2 - ;
                edge[k].c = a2;
                k++;
            }
        }
        ; i <= n; i++)       //初始化father数组
        {
            father[i] = i;
        }

        kruskal();
        a1++;
    }
    ;
}

2018-04-01

05-11 15:54