【题目描述】
有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?
【输入】
n(城市数,1<≤n≤100)
e(边数)
以下e行,每行3个数i,j,wiji,j,wij,表示在城市i,j之间修建高速公路的造价。
【输出】
n-1行,每行为两个城市的序号,表明这两个城市间建一条高速公路。
【输入样例】
5 8 1 2 2 2 5 9 5 4 7 4 1 10 1 3 12 4 3 6 5 3 3 2 3 8
【输出样例】
1 2 2 3 3 4 3 5
#include <bits/stdc++.h> using namespace std; struct Node { int x, y, w; Node(int x, int y, int w) { this->x = x; this->y = y; this->w = w; } bool operator<(const Node &b) const { return (w > b.w); } }; void show(vector<vector<int>> &a) { for (int i = 1; i < a.size(); i++) { for (int j = 1; j < a[i].size(); j++) { cout << setw(2) << a[i][j] << " "; } cout << endl; } } vector<pair<int, int>> prim(vector<vector<int>> &a) { vector<pair<int, int>> ans; // 边集 unordered_set<int> vs; // // 点集 vs.insert(1); // 从点1开始 for (int t = 2; t < a.size(); t++) { // 次数 priority_queue<Node> es; // 边集 for (auto &v : vs) { // 遍历起点 for (int i = 1; i < a.size(); i++) { if (vs.find(i) != vs.end()) { continue; // 点j在vs中 } es.push(Node(v, i, a[v][i])); } } Node nt = es.top(); // 取最短的边 ans.push_back(make_pair(nt.x, nt.y)); vs.insert(nt.y); } return ans; } int main() { // freopen("in.txt", "r", stdin); int n, e; // 城市数n,边数e scanf("%d%d", &n, &e); vector<vector<int>> a(n + 1, vector<int>(n + 1, INT_MAX)); int x, y, w; for (int i = 0; i < e; i++) { scanf("%d%d%d", &x, &y, &w); a[x][y] = a[y][x] = w; } // show(a); vector<pair<int, int>> ae = prim(a); sort(ae.begin(), ae.end()); for (auto &e : ae) { printf("%d %d\n", e.first, e.second); } return 0; }