最小生成樹是乙個比較簡單資料結構,形成最小生成樹的方式有兩種。
最小生成樹是有圖生成樹,保證樹的每條邊的權值之和最小的生成樹就叫做最小生成樹,這一類的題目起初比較基礎,主要是熟悉模板,poj 1258 也就是這樣的題目,非常適合剛剛學習的人。
兩種方法的思路分別是找邊和找點,簡單點說就是,找到全集中最小的邊(或者是距離最近的點),將他們連線起來,最終形成的樹就是最小生成樹。
第一種方法,prim演算法,時間複雜度較高不經常使用,是一種找點的方式
這種方式做題的時候最重要的就是要注意,必須注意是不是有一模一樣的邊,很容易出現類似錯誤,但是由於不經常使用,這裡不多做闡述,以後回單獨講解。
列出模板:
int table[maxn][maxn];//用來記錄每個點的始點到終點的距離
//例如table[1][2] = 3;表示的是1到2 的距離是3;
//這就是prim的比較差勁的地方,他必須每次都完全遍歷尋找
int dis[maxn];//邊的最小距離
int used[maxn];//標記是否使用過
void prim()}}
printf("%d\n",sum);
}
這個題目就是 乙個套入模板的板子題,下面是這個題的解答
#include
#include
#include
#include
#include
#include
#include
#define maxn 105
#define inf 0x3f3f3f3f
using
namespace
std;
int n;
int table[maxn][maxn];
int dis[maxn];
int used[maxn];
void prim()}}
printf("%d\n",sum);
}int main()
}prim();
}return
0;}
第二種方法 kruskal演算法,是一種找邊的思想
大體思路就是,通過尋找不是同乙個樹上的最短的邊,將他們合在同乙個樹上形成最小生成樹。在這個題目上應用,並不是太明顯,這個題資料量太小
詳細的就看**注釋吧!主要是應用了並查集,
如果沒有接觸過並查集,可以看一下,再回來看下面的**
#include
#include
#include
#include
using
namespace
std;
const
int maxn = 105;
struct edge
} edges[maxn*maxn];
int p[maxn];
int n;
//並查集的查詢函式,帶有壓縮路徑
int _find(int x)
return p[x];
}int kruskal()
}return ans;
}int main()
sort(edges, edges+n*n);
printf("%d\n", kruskal());
}return
0;}
POJ 1258 最小生成樹
include include struct fiberfiber 10000 struct farmsfarms 100 void exchange struct fiber fiber,int i,int j int partition struct fiber fiber,int p,int ...
poj1258 最小生成樹
題目鏈結在這裡 題目描述 john要給村民通寬頻!他現在已經有了乙個高速網路了,現在想將村民相互連線起來。現給出村民之間的距離,求將他們連線起來的最小花費為多少。思路分析 最小生成樹,盤它就完事了。如下 include include include include include using na...
POJ 1258 最小生成樹 Prim
乙個有n個節點的連通圖的生成樹是原圖的極小連通子圖,且包含原圖中的所有n個結點,並且有保持圖連通的最少的邊。最小生成樹可以用kruskal演算法或者prim演算法求出。kruskal演算法的過程為不斷對子圖進行合併,直到形成最終的最小生成樹。prim演算法的過程則是只存在乙個子圖,不斷選擇頂點加入到...