作題時發現本身只會打\(Kruskal\) kk/,因此來補課來了ios
\(v\) 個點的無向圖中,取 \(|v| - 1\)條邊,組成的權值最小的樹c++
mind:spa
將頂點分爲兩類,一類是在查找的過程當中已經包含在樹中的(假設爲 A 類),剩下的是另外一類(假設爲 B 類),起始狀態所有頂點都歸爲 B 類。在找最小生成樹時,選定任意一個頂點做爲起始點,並將之從 B 類移至 A 類;而後找出 B 類中到 A 類中的頂點之間權值最小的頂點,將之從 B 類移至 A 類,如此重複,直到 B 類中沒有頂點爲止。所走過的頂點和邊就是該連通圖的最小生成樹code
#include<bits/stdc++.h> using namespace std; #define re register #define il inline il int read() { re int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar(); return x*f; } #define inf 123456789 #define A 5005 #define B 200005 struct edge{ int v,w,next; }e[B<<1]; int head[A],dis[A],cnt,n,m,tot,now=1,ans; bool vis[B]; il void add(int u,int v,int w) { e[++cnt].v = v;e[cnt].w = w;e[cnt].next = head[u];head[u] = cnt; } il void init() { n = read(),m = read(); for(re int i = 1,u,v,w;i <= m;++i){ u = read(),v = read(),w = read(); add(u,v,w),add(v,u,w); } } il int prim() { for(re int i = 2;i <= n; ++i) dis[i] = inf; for(re int i = head[1];i;i = e[i].next){ dis[e[i].v] = min(dis[e[i].v],e[i].w); } while(++tot<n){ re int minn = inf; vis[now] = 1; for(re int i = 1;i <= n;++i){ if(!vis[i]&&minn > dis[i]){ minn = dis[i]; now = i; } } ans += minn; for(re int i = head[now];i;i = e[i].next){ re int v = e[i].v; if(dis[v] > e[i].w&&!vis[v]){ dis[v] = e[i].w; } } } return ans; } int main(){ init(); printf("%d",prim()); return 0; }
選取權值較小的邊,並依次鏈接,若出現環則跳過此邊(用並查集來判斷是否存在環)繼續搜,直到已經使用的邊的數量比總點數少一便可get
/* work by:Ariel */ #include<iostream> #include<cstdio> #include<queue> #include <algorithm> using namespace std; const int M = 500010; int read(){ int f = 1,x = 0;char c = getchar(); while(c < '0'||c > '9'){if(c == '-')f = -1,c = getchar();} while(c <= '9'&&c >= '0'){x = x*10 + c - '0',c = getchar();} return f*x; } struct edge{ int u,v,w; }e[M]; int n,m,fa[M]; int find(int x){ if(fa[x] == x) return x; return fa[x] = find(fa[x]); } int cmp(edge x,edge y){ return x.w < y.w; } int pd(int x,int y){//判斷x,y是否在圖上 int a = find(x); int b = find(y); if(a != b){ fa[b] = a; return 1; } return 0; } int main() { n = read(),m = read(); for (int i = 1;i <= m; i++){ scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); } int cnt = 0,ans = 0; sort(e + 1,e + m + 1,cmp); for (int i =1 ;i <= n; i++) fa[i] = i; for (int i = 1;i <= m; i++){ if (pd(e[i].u,e[i].v) == 1){ cnt ++; ans += e[i].w; } if(cnt == n-1) break; } if(cnt == n-1) printf("%d",ans); else printf("orz"); return 0; }