浙大版《数据结构(第2版)》题目集-习题8.5

习题8.5 畅通工程之局部最小花费问题 (35point(s))

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

Example:

#include <iostream>
#include <vector>
#include <list>

using namespace std;

struct Edge {
    int src;
    int dst;
    int cost;
};

vector<int> com;
vector<bool> visited;
int component;

void DFS(vector<list<Edge>> &G, int v)
{
    if(visited[v]) return ;
    visited[v] = true;
    com[v] = component;
    for(auto &x : G[v]) {
        DFS(G, x.dst);
    } 
}

int main()
{
    int N;
    cin >> N;
    list<Edge> edge;
    vector<list<Edge>> adj(N+1);
    for(int i = 0; i < N*(N-1)/2; i++) {
        int src, dst, cost, build;
        cin >> src >> dst >> cost >> build;
        if(build == 1) {
            adj[src].push_back({src, dst, cost});
            adj[dst].push_back({dst, src, cost});
        } else {
            auto next = edge.begin();
            for(; next != edge.end(); next++) {
                if(cost <= next->cost) break;
            }
            edge.insert(next, {src, dst, cost});
        }
    }
    com.resize(N+1);
    visited.resize(N+1);
    for(int i = 1; i <= N; i++) {
        if(!visited[i]) {
            ++component;
            DFS(adj, i);
        }
    }
    int cost = 0;
    if(component > 1) {
        for(auto &x: edge) {
            if(com[x.src] != com[x.dst]) {
                cost += x.cost;
                int Max = max(com[x.src], com[x.dst]);
                int Min = min(com[x.src], com[x.dst]);
                for(auto &y : com) {
                    if(y == Max) y = Min;
                }
            }
        }
    }
    cout << cost << endl;
    return 0;
}

思路:

  1. 没有建道路的边,按升序排队
  2. 计算连通分量
  3. 按照升序的待建边,连接不同的连通分量。

猜你喜欢

转载自blog.csdn.net/u012571715/article/details/113483764
今日推荐