圖的最小生成樹
阿新 • • 發佈:2021-12-13
Prim演算法
核心思想:貪心的將一個又一個點加入集合,而加入的每個點都儘可能使邊權最小,這樣可以使用STL的priority_queue來維護。
struct edge{int to,cost;};//to表示邊的終點,cost表示權值 typedef pair<int,int> P;//P.first表示已有點集到P.second這個點的邊權最小值 priority_queue <P,vector<P>,greater<P> >que;//用於儲存最小邊權值的優先佇列 bool visited[MAX_V];//查詢點是否被訪問 vector<edge> G[MAX_V]; int V;//頂點數 int Prim() { for(int i=0;i<V;i++) { visited[i]=false; } int res=0; que.push(0,0); for(int i=1;i<=V;i++) { while(true) { P p=que.top(); if(!visited[p.second]) { res=res+p.first; for(int j=0;j<G[p.second].size();j++) { que.push(P(G[p.second].cost,P(G[p.second].to))); } break; } } } return res; }
Kruskal演算法
核心思想:把邊的權值從小到大排一遍,一條一條加入圖中,不產生圈即為有效。為了簡化,可以用並查集判斷是否構成圈。
struct edge{ int u,v,cost};//u為邊的起點,v為邊的終點,cost為邊的權值 bool cmp(const edge& e1,const edge & e2) { return e1.cost < e2.cost; } edge es[MAX_E];//儲存所有的邊 int V,E;//頂點數和邊數 //init,unite,same函式均為並查集的函式,請跳轉至並查集部分 int Kruskal() { sort(es,es+E,cmp); init(V); int res=0; for(int i=0;i<E;i++) { edge e=es[i]; if(!same(e.u,e.v)) { unite(e.u,e.v); res=res+e.cost; } } return res; }