洛谷3366 最小生成树(Prim + 堆优化)
2017-07-28 21:58
295 查看
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz输入输出格式
输入格式:第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式:
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
输入输出样例
输入样例#14 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出样例#1
7
时空限制
1000ms,128M数据规模
对于20%的数据:N<=5,M<=20对于40%的数据:N<=50,M<=2500
对于70%的数据:N<=500,M<=10000
对于100%的数据:N<=5000,M<=200000
日常发板,感觉自己不是很常用的算法都没正经学……
Prim优化后的复杂度仿佛很谜啊,但这题交上去好像还是会比Kruskal快些的
代码
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int Maxn = 0x3f3f3f3f; const int N = 5e4 + 5, M = 4e5 + 5; int dis , n, m, Ans; bool vis ; struct Edge { int to, cst; Edge *nxt; }p[M], *T = p, *lst ; struct point { int s, t; inline bool operator < (const point &x) const { return s < x.s; } point() {} point(const int &Ss, const int &Tt): s(Ss), t(Tt) {} }; struct SmaRt { point g[M]; int len; inline void Pop() { g[1] = g[len--]; int now = 1, nxt = 2; point res = g[1]; while (nxt <= len) { if (nxt < len && g[nxt | 1] < g[nxt]) nxt |= 1; if (g[nxt] < res) g[now] = g[nxt], nxt = (now = nxt) << 1; else break; } g[now] = res; } inline void Push(const point &res) { g[++len] = res; int now = len, nxt = len >> 1; while (nxt) { if (res < g[nxt]) g[now] = g[nxt], nxt = (now = nxt) >> 1; else break; } g[now] = res; } }Q; inline void addEdge(const int &x, const int &y, const int &z) { (++T)->nxt = lst[x]; lst[x] = T; T->to = y; T->cst = z; (++T)->nxt = lst[y]; lst[y] = T; T->to = x; T->cst = z; } inline int get() { char ch; int res; while ((ch = getchar()) < '0' || ch > '9'); res = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') res = (res << 3) + (res << 1) + ch - '0'; return res; } int main() { n = get(); m = get(); int x, y; while (m--) { x = get(); y = get(); addEdge(x, y, get()); } memset(dis, Maxn, sizeof(dis)); Q.Push(point(dis[1] = 0, 1)); for (int i = 1; i <= n; ++i) { while (vis[Q.g[1].t] && Q.len) Q.Pop(); if (!Q.len) return puts("orz"), 0; vis[x = Q.g[1].t] = true; Q.Pop(); Ans += dis[x]; for (Edge *e = lst[ 4000 x]; e; e = e->nxt) if (!vis[y = e->to] && dis[y] > e->cst) Q.Push(point(dis[y] = e->cst, y)); } printf("%d\n", Ans); return 0; }
相关文章推荐
- 求最小生成树(暴力法,prim,prim的堆优化,kruskal)
- HDU1102 - Constructing Roads 用优先队列优化Prim最小生成树
- 最小生成树(模板)洛谷3366
- hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】
- 【模板】Prim+堆优化 最小生成树
- 最小生成树模板(prim+kruskal+prim的优化)
- JAVA实践优化Prim最小生成树算法
- [洛谷3366]【模板】最小生成树
- (洛谷 3366)【模(mú)板】最小生成树
- 最小生成树---prim模板(二叉堆优化)
- 最小生成树--prim+优先队列优化模板
- 最小生成树prim+邻接表优化
- 洛谷3366 最小生成树模板题
- 最小生成树MST——Prim实现
- Prim 算法生成的最小生成树
- 最小生成树-prim
- Agri-Net(最小生成树模板 prim)
- 图论 最小生成树 Prim Kruskal POJ 3255 POJ 3723 POJ 3169
- hdoj 1863 畅通工程【最小生成树,kruskal&&prim】
- 最小生成树 Prim(普里姆)算法和Kruskal(克鲁斯特尔)算法