圖知識小結5-kruskal演算法的陣列模擬實現與應用
阿新 • • 發佈:2018-12-11
#include <bits/stdc++.h> using namespace std; const int MAX_EDGE = 100000; const int MAX_VERTICES = 100; struct Edge{ int len, u, v; } edge[MAX_VERTICES]; int fa[MAX_VERTICES], nv, ne; bool cmp(Edge a, Edge b){ return a.len < b.len; } int get_ancestor(int x){ if(fa[x] == x){ return fa[x]; } return fa[x] = get_ancestor(fa[x]); } bool merge(int x, int y){ int ance_x = get_ancestor(x); int ance_y = get_ancestor(y); if(ance_x != ance_y){ fa[ance_x] = ance_y; return true; } return false; } void init(){ for(int i = 0 ; i <= nv ; i++){ fa[i] = i; } } int main(){ cin >> nv >> ne; init(); for(int i = 1 ; i <= ne ; i++){ cin >> edge[i].u >> edge[i].v >> edge[i].len; } sort(edge + 1, edge + ne + 1, cmp); //abandon the first space in edge array int rest_vertices = nv, weight_sum = 0, sub_cost = -1; //weight_sum : weight on MST, sub_cost : the maximum edge's weight in MST for(int i = 1 ; i <= ne && rest_vertices > 1 ; i++){ // the last situation will be rest_vertices == 1 cause there is just one nodes left if(merge(edge[i].u, edge[i].v)){ weight_sum += edge[i].len; rest_vertices--; if(edge[i].len > sub_cost){ sub_cost = edge[i].len; } } } cout << "Minimum cost : " << weight_sum << endl; cout << "The maximum edge's weight in MST : " << sub_cost << endl; return 0; }
上面的程式碼可以直接用到CCF 201703-4地鐵修建,需要改一下引數和去掉輸出提示,程式碼如下:
#include <bits/stdc++.h> using namespace std; const int MAX_EDGE = 200050; const int MAX_VERTICES = 100050; struct Edge{ int len, u, v; } edge[MAX_EDGE]; int fa[MAX_VERTICES], nv, ne; bool cmp(Edge a, Edge b){ return a.len < b.len; } int get_ancestor(int x){ if(fa[x] == x){ return fa[x]; } return fa[x] = get_ancestor(fa[x]); } bool same(int x, int y){ return get_ancestor(x) == get_ancestor(y); } bool merge(int x, int y){ int ance_x = get_ancestor(x); int ance_y = get_ancestor(y); if(ance_x != ance_y){ fa[ance_x] = ance_y; return true; } return false; } int main(){ cin >> nv >> ne; for(int i = 1 ; i <= nv ; i++){ fa[i] = i; } int sub_cost = 0; for(int i = 1 ; i <= ne ; i++){ cin >> edge[i].u >> edge[i].v >> edge[i].len; if(edge[i].u == 1 && edge[i].v == nv || edge[i].u == nv && edge[i].v == 1){ sub_cost = edge[i].len; } } sort(edge + 1, edge + ne + 1, cmp); //abandon the first space in edge array int rest_vertices = nv, weight_sum = 0; //weight_sum : weight on MST, sub_cost : the maximum edge's weight in MST for(int i = 1 ; i <= ne && rest_vertices > 1 ; i++){ // the last situation will be rest_vertices == 1 cause there is just one nodes left if(same(1,nv)){ break; } else if(merge(edge[i].u, edge[i].v)){ weight_sum += edge[i].len; rest_vertices--; sub_cost = edge[i].len; } } cout << sub_cost; return 0; } //此題使用最小生成樹的思路去做並沒有問題,但並不是要得到最小生成樹 //而是找到連通起點和最終點之之間的最小路徑中的最大邊
遺憾的是,用克魯斯卡寫出來也是80分,目前還沒有解決
2018/12/9解決掉了,這個是因為邊集陣列開小了,因為開始邊集陣列大小誤開成了edge[MAX_VERTICES],改成edge[MAX_EDGE]之後再提交就是100分了