poj3522
给定一个简单图,n个点,m条边( 1<=n<=100,0 ≤ m ≤ n(n − 1)/2 ),要求一颗生成树,使得其最大边与最小边的差值是所有生成树中最小的,输出最小的那个差值。
思路:枚举所有边,用kruskal求生成树,不断更新最小值就可以了。
优化:可以先找到所有节点的最大边中的最小值,枚举到这条边就可以结束了。
代码只写出思路,没时间测试,仅供参考。
struct Edge { int src; int dst; int len; } int n; vector<Edge> sorted_graph; vector<int> father; vector<int> degree; void Union(int node_a, int node_b) { int father_a = Find(node_a); int father_b = Find(node_b); if (father_a < 0 || father_b < 0 ||father_a >= n || father_b >= n) { assert(0); return; } if (degree[father_a] > degree[father_b]) { father[father_b] = father_a; degree[father_a] += degree[father_b]; } else { father[father_a] = father_b; degree[father_b] += degree[father_a]; } } int Find(int node_a) { if (father[node_a] == node_a) return node_a; return father[node_a] = Find(father[node_a]); } vector<Edge> Kruska(int pos) { vector<Edge> tree; for (int i = 0; i < n; ++i) { father[i] = i; degree[i] = 1; } for (int i = pos; pos < sorted_graph.size(); ++i) { const Edge& e = sorted_graph[i]; if (Find(e.src) != Find(e.dst)) { Union(e.src, e.dst); tree.push_back(e); } if (tree.size() == n - 1) { return tree; } } return vector<Edge>(); } int main() { GenerateGraph(); SortEdges(); int min_interval = 0x7fffffff; bool min_tree_exist = false; for (int i = 0; i < sorted_graph.size(); ++i) { vector<Edge> res = Kruska(i); if (res.size() < n - 1) { continue; } min_interval = min(min_interval, res.back().len - res.front().len); min_tree_exist = true; } if (min_tree_exist) { cout << "The result is " << min_interval << endl; } else { cout << "The tree is not exist!" << endl; } return 1; }
Passion, patience, perseverance, keep it and move on.

浙公网安备 33010602011771号