Đề bài
Cho đồ thị vô hướng có trọng số không âm G=<V,E> được biểu diễn dưới dạng danh sách cạnh trọng số. Hãy viết chương trình tìm cây khung cực tiểu.
Input
- Dòng đầu tiên chứa 3 số n, m, s là số đỉnh, số cạnh của đồ thị và đỉnh bắt đầu (1 <= n <= 1000, 1 <= m <= n*(n-1)/2).
- M dòng tiếp theo, mỗi dòng là 2 số u, v biểu diễn cạnh u, v của đồ thị (1 <= u, v <= n).
- Ràng buộc: 1 <= n <= 1000; 1 <= m <= n*(n-1)/2; Trọng số các cạnh là số nguyên không âm không vượt quá 100;
Output
- Ghi ra file văn bản lab_t_output.OUT.
Sample
Input |
Output |
6 9
1 2 12
1 3 4
2 3 1
2 4 5
2 5 3
3 5 2
4 5 3
4 6 10
5 6 8
|
MST: 18
2 3 1
3 5 2
4 5 3
1 3 4
5 6 8
|
Giải
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
using ll = long long;
struct edge {
int u;
int v;
int w;
};
const int maxN = 100001;
const int INF = 1e9; // so vo cung
int n, m; // n: so dinh, m: so canh
int parent[maxN], sz[maxN];
vector<edge> canh;
void make_set() {
for(int i = 1; i <= n; i++) {
parent[i] = i;
sz[i] = 1;
}
}
int find (int v) {
if(v == parent[v]) {
return v;
}
return parent[v] = find(parent[v]);
}
bool Union(int a, int b) {
a = find(a);
b = find(b);
if(a == b) {
return false; // khong the gop a, b voi nhau
}
if(sz[a] < sz[b]) {
swap(a, b);
}
parent[b] = a;
sz[a] + sz[b];
return true;
}
void inp() {
cin >> n >> m;
for(int i=0; i<m; i++) {
int x, y, w;
cin >> x >> y >> w;
edge e;
e.u = x;
e.v = y;
e.w = w;
canh.push_back(e);
}
}
bool cmp(edge a, edge b) {
return a.w < b.w;
}
void kruskal() {
// Tao cay khung cuc tieu rong
vector<edge> mst;
int d = 0;
// Sort danh sach canh theo chieu dai tang dan
sort(canh.begin(), canh.end(), cmp);
// Lap qua cac canh
for(int i=0; i<m; i++) {
if(mst.size() == n-1) {
break;
}
edge e = canh[i]; // chon canh e la canh nho nhat
if(Union(e.u, e.v)) {
mst.push_back(e);
d += e.w;
}
}
// Tra ve ket qua
if(mst.size() != n-1) {
cout << "Do thi khong lien thong !\n"; // Do thi khong co cay khung
} else {
cout << "MST: " << d << endl;
for(auto it: mst) {
cout << it.u << " " << it.v << " " << it.w << endl;
}
}
}
int main() {
// Chuyen NHAP, XUAT thanh file
freopen("lab_6_input.INP", "r", stdin);
freopen("lab_6_output.OUT", "w", stdout);
// INPUT
inp();
make_set();
// OUTPUT
kruskal();
}
|