全地区畅通需要的最低成本

  1. 某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建快速路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全地区畅通需要的最低成本。

输入格式:

输入的第一行给出村庄数目N (1≤N≤100);随后的N(N−1)/2行对应村庄间道路的成本及修建状态:每行给出4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态 — 1表示已建,0表示未建。

输出格式:

输出全省畅通需要的最低成本。

输入样例:

4

1 2 1 1

1 3 4 0

1 4 1 1

2 3 3 0

2 4 2 1

3 4 5 0

输出样例:

3

(1)分析
由于是稠密图,所以采用Prim算法。二维数组数组存储图,数组存储路费,visit[]记录该点是否已经加入最小生成树中。首先以第一个结点作为最小生成树的初始结点,然后找出与最小生成树中各结点权重最小边,且该结点不在最小生成树中(确保无环路),然后加入到最小生成树中,更新没有在最小生成树中的结点和最小生成树中各结点权重边。循环上述步骤直到生成最小生成树,过程中最小生成树中各结点权重最小边的权重和就是最低成本。
时间复杂度:O(n²)
(2)代码及运行

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int valmap[110][110]; //map数组存储图
    int value[110]; //数组存储路费
    int visit[110]= {0};//表示该点是否已经加入最小生成树中
    int n,i,j;
    cin>>n;
    memset(value,1,sizeof(value));
    int m=n*(n-1)/2;
    for(i=1; i<=m; i++)
    {
        int x1,x2,x3,x4;
        cin>>x1>>x2>>x3>>x4;
        if(!x4)
        {
            valmap[x1][x2]=x3;
            valmap[x2][x1]=x3;
        }
        else
        {
            valmap[x1][x2]=0;
            valmap[x2][x1]=0;
        }
    }
    for(i=1; i<=n; i++)
    {
        valmap[i][i]=0;
    }
    int start=1;
    visit[start]=1;
    for(i=1; i<=n; i++)//初始化
    {
        value[i]=valmap[start][i];
    }
    int num=0;
    for(i=1; i<=n-1; i++)//最多n-1条路
    {
        int minval=99999;
        for(j=1; j<=n; j++)
        {
            if(!visit[j] && (value[j]<minval))
            {
                minval=value[j];
                start=j;
            }
        }
        if(minval==99999)break;
        num+=minval;
        visit[start]=1;
        for(j=1; j<=n; j++)
        {
            if (!visit[j] && valmap[start][j]<value[j])
            {
                value[j]=valmap[start][j];
            }

        }
    }
    cout<<num;
    return 0;
}
### 回答1: 这是一个小生成树问题,可以使用Kruskal算法或Prim算法来解决。 以下是使用Prim算法的示例代码: ```python import heapq def prim(edges, n): # 初始化 visited = [False] * n mst = [] heap = [(0, 0)] # (cost, node) while heap: cost, node = heapq.heappop(heap) if visited[node]: continue visited[node] = True mst.append((cost, node)) for c, nei in edges[node]: if not visited[nei]: heapq.heappush(heap, (c, nei)) return sum(cost for cost, _ in mst) # 示例输入: n = 5 edges = [ [(1, 1), (2, 3)], [(1, 0), (3, 4), (4, 2)], [(2, 1), (4, 5)], [(3, 1), (4, 3), (5, 4)], [(5, 3)], ] print(prim(edges, n)) # 输出 7 ``` 其中,`edges`为邻接表形式的图,`n`为节点数。每个元素为一个列表,包含该节点所连接的其他节点及其边权。在本例中,第一个列表表示节点0连接到节点1和节点3,边权分别为1和3。 ### 回答2: 首先,我们可以将整个地区看做一个图,每个村落代表一个节点,道路代表节点的边。根据题目描述,我们需要找到一种小生成树的方式,即使用少的费用连接所有的村落。 一种常用的解决这个问题的算法是Prim算法。以下是用于计算地区畅通所需低成本的具体步骤: 1. 初始化一个包含所有村落的集合V,一个初始化为空的集合E(用于存储选择的边),另外创建一个大小为n的数组cost[],用于存储从当前生成树到未添加的节点的小路径。 2. 随机选择一个起始村落,将其添加到生成树中,从集合V中移除。 3. 遍历集合V中的所有节点v,对于每个节点v,计算从生成树中的节点到v的路径cost[v],找到小的路径对应的边e。 4. 将边e添加到集合E中,将节点v从集合V中移除。 5. 重复步骤3和步骤4,直到集合V为空。 6. 计算集合E中所有边的费用之和,即为地区畅通所需的低成本。 注意:如果题目要求输出具体的路径,可以在步骤4中记录每个节点v的来源节点,后通过回溯的方式得到具体路径。 通过使用Prim算法,可以在O(n^2)的时复杂度内解决这个问题,其中n为村落数量。 ### 回答3: 假设偏远地区有n个村落,我们可以使用图的小生成树算法来解决这个问题。下面是程序的伪代码: 1. 输入偏远地区的村落数量n和每两个村落之修建道路的费用cost[n][n](cost[i][j]表示村落i与村落j之修建道路的费用)。 2. 创建一个大小为n的布尔数组visited,表示每个村落的访问状态,初始时所有村落都未访问。 3. 将第一个村落设为起始村落,设置visited[0]为true。 4. 创建一个整型变量minCost,表示地区畅通所需的低成本,初始值为0。 5. 创建一个整型变量count,表示已访问的村落数量,初始值为1。 6. 当count小于n时,执行以下循环: - 创建两个整型变量minCostIndex和minCostValue,分别用于记录小费用的村落下标和小费用的值,初始值为-1。 - 遍历已访问的村落,对于每个已访问的村落i,遍历未访问的村落j,找到小的cost[i][j]。 - 如果minCostValue为-1或者找到了比minCostValue小的费用,更新minCostValue和minCostIndex。 - 将minCostIndex对应的未访问村落设为已访问,增加count的值,更新minCost的值。 7. 输出minCost,即地区畅通所需的低成本。 这样,我们就可以通过以上的程序来计算出地区畅通所需的低成本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值