P3366【模板】最小生成树
Kruskal
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 5005; 5 int fa[maxn], n, m, ans = 0; 6 bool flag = false; // 判断图是否连通 7 struct edge { 8 int u, v, w; 9 }eds[200005]; 10 bool cmp(const edge x, const edge y) { 11 return x.w < y.w; 12 } 13 int find(int x) { 14 if (x != fa[x]) fa[x] = find(fa[x]); 15 return fa[x]; 16 } 17 void kruskal() { 18 int cnt = 0; 19 sort(eds+1,eds+1+m,cmp); 20 for (int i = 1; i <= m; i++) { 21 int fx = find(eds[i].u); 22 int fy = find(eds[i].v); 23 if (fx == fy) continue; 24 ans += eds[i].w; 25 fa[fx] = fy; 26 if (++cnt == n-1) { 27 flag = true; 28 break; 29 } 30 } 31 } 32 int main() { 33 scanf("%d%d",&n,&m); 34 for (int i = 1; i <= m; i++) 35 scanf("%d%d%d",&eds[i].u,&eds[i].v,&eds[i].w); 36 for (int i = 1; i <= n; i++) fa[i] = i; 37 kruskal(); 38 if (flag) printf("%d\n",ans); 39 else puts("orz"); 40 return 0; 41 }
Prim+堆优化
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 5005; 4 struct edge{ 5 int u, dis; 6 bool operator < (const edge &tmp) const { return dis > tmp.dis; } 7 }; 8 priority_queue<edge> que; 9 bool vis[maxn]; 10 int n, m, ans, dis[maxn]; 11 vector<edge> ve[maxn]; // 邻接链表 12 int main(){ 13 memset(dis,0x3f3f3f3f,sizeof(dis)); 14 scanf("%d%d",&n,&m); 15 for(int i = 1; i <= m; i++) { 16 int u, v, w; scanf("%d%d%d",&u,&v,&w); 17 ve[u].push_back(edge{v,w}); 18 ve[v].push_back(edge{u,w}); 19 } 20 21 dis[1] = 0; que.push((edge){1,0}); 22 int k = 0; 23 while(!que.empty()&& k<n){ 24 edge x = que.top(); que.pop(); 25 if(vis[x.u]) continue; 26 vis[x.u] = true; ++k; ans += x.dis; 27 for (int i = 0; i < ve[x.u].size(); i++) { 28 int to = ve[x.u][i].u, d = ve[x.u][i].dis; 29 if (dis[to] > d) 30 dis[to] = d, que.push((edge){to,d}); 31 } 32 } 33 if (k < n) puts("orz"); 34 else printf("%d",ans); 35 return 0; 36 }