7-10 公路村村通

7-10 公路村村通 (30 分)

现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

输入格式:

输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。

输出格式:

输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。

输入样例:

6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3

输出样例:

12

思路:该题为典型的最小生成树问题,但是 有个测试点一直过不去,翻看对应的习题集,给出的数据是n为1000,m为3000。不过还是没有找到错误的地方难受,希望哪位好心人帮忙看一下然后告知我多谢了。解题思路为,采用的算法为克鲁斯卡尔算法,将边按从小到大排序,然后每次选出最小的一条边加入到图中但是不能构成回路,当边数为顶点数减一时,则最小生成树构造成功。两个关键步骤:1.每次选出最小的一条边可以采用快速排序算法或者最小堆,我用的是快速排序。2.如何判断两个顶点是否连通,这里采用并查集的方法。

代码如下:

/************************************************************************
*
* 文件名:8.1.1.cpp
*
* 文件描述:
*
* 创建人:  fdk

* 时  间:  2018-10-05
*
* 版本号:1.0
*
* 修改记录:有个测试点一直过不去,翻看对应的习题集,给出的数据是n为1000,m为3000
*            不过还是没有找到错误的地方难受。
*
************************************************************************/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max 100
using namespace std;
struct edge
{
    int u;
    int v;
    int w;
};
struct edge e[3001];
int n, m;
int f[1001] = {0}, sum = 0, counts = 0;

void quickSort(int left, int right)
{
    int i, j;
    struct edge t;
    if (left > right)
    {
        return;
    }
    i = left;
    j = right;
    while (i != j)
    {
        while (e[j].w >= e[left].w && i < j)
        {
            j--;
        }
        while (e[i].w <= e[left].w && i < j)
        {
            i++;
        }
        if (i < j)
        {
            t = e[i];
            e[i] = e[j];
            e[j] = t;
        }
    }
    t = e[left];
    e[left] = e[i];
    e[i] = t;

    quickSort(left, i-1);
    quickSort(i+1, right);
    return;
}

int getf(int v)
{
    if (f[v] == v)
    {
        return v;
    }
    else
    {
        f[v] = getf(f[v]);
        return f[v];
    }
}

int merge(int v, int u)
{
    int t1, t2;
    t1 = getf(v);
    t2 = getf(u);
    if (t1 != t2)
    {
        f[t2] = t1;
        return 1;
    }
    return 0;
}
int main()
{
    int i;

    cin >> n >> m;

    for (i = 1; i <= m; i++)
    {
        cin >> e[i].u >> e[i].v >> e[i].w;
    }
    quickSort(1, m);

    for (i = 1; i <= m; i++)
    {
        f[i] = i;
    }
    counts = n;
    for (i = 1; i <= m && counts > 1; i++)
    {
        if (merge(e[i].u, e[i].v))
        {
            sum += e[i].w;
            counts--;
        }
    }
    if (counts == 1)
    {
        cout << sum;
    }
    else
    {
        cout << "-1";
    }
    return 0;
}

 

你可能感兴趣的:(7-10 公路村村通)