通過最小生成樹(prim)和最短路徑優化引出的向前星存圖,時至今日才徹底明白了。。
head[i]儲存的是父節點為i引出的最後一條邊的編號,
next負責把head[i]也就是i作為父節點的所有邊連線起來,next也是存的編號
,在所存的edge結構體中,只有w是儲存邊的值,而u是儲存的子節點。
這樣設定的話,由head[i]就可以引出所有與i相關的邊和點,
顯而易見,這樣的存放方法空間+時間複雜度雙優化,比鄰接矩陣是優化多了。。
然後就是prim演算法,
最小生成樹的一種演算法,適用於稠密圖,因為是以點更新的,正好與之前的克魯斯卡爾演算法互補了,
不過**比k長,思路也難一些,大致和迪傑差不多,也用了dis陣列,目測也就是更新dis值的時候不同(其實很不同,就形式差不多而已)
,下面附上**,借鑑某位luogu大神的題解,真的很簡潔明瞭了,在luogu上比 k 快了大概一倍240+ms。
其他優化用了快讀+re。
1 #include 2 #include3 #include 4 #include 5 #include 6
#define maxn 5002
7#define maxm 200001
8#define inf 9999
9#define re register
1011
using
namespace
std;
1213
int n,m,cnt,sum=0,k=0;14
inta,b,c;
15int
dis[maxn],head[maxn],vis[maxn];
1617 typedef pair pii;
18 priority_queue ,greater>q;
1920
struct
edge
21edge[maxm*2
];24 inline int
read()
2533
void add(int u,int v,int
w)34
4041
void
prim()
4260}61
} 62}63
64int
main()
6576
prim();
77if(k==n)printf("%d"
,sum);
78else cout<<"
orz";79
return0;
80 }
最小生成樹 Prim演算法(模板)
基本演算法 首先以乙個結點作為最小生成樹的初始結點,然後以迭代的方式找出與最小生成樹中各結點權重最小邊,並加入到最小生成樹中。選擇一條權值最小,且一端點a已加入生成樹,另一端點b在剩餘結點集內的邊作為最小生成樹上的邊,同時將b列入生成樹的已有點集中。當所有結點都加入到最小生成樹中之後,就找出了連通圖...
最小生成樹prim演算法模板
include using namespace std const int inf 0x3f3f3f3f 最大值,方便計算 int n,m n是點的個數,m是邊的數量 int dis 105 vis 105 dis是判斷未加入生成樹的頂點到已知生成樹的最短距離,vis判斷是否已經加入生成樹 int ...
模板) 最小生成樹Prim演算法
演算法跟dijkstra很像 但是要特別注意兩點 1.最好使用乙個額外的陣列來保證每個點只被訪問一次,否則的話應該保證在35行處使用e.dis dis e.num 而不僅是 否則會造成一些相等的額外相加。2.40行的地方要注意與dijkstra的區別!不是加而是直接換!include include...