【最小生成树】[Scoi2012] bzoj2753 滑雪与时间胶囊

来源:互联网 发布:php mysql环境搭建 编辑:程序博客网 时间:2024/04/27 22:39

题目点这里


像我这种出来培训也不忘刷水题的:)


orz其实这题感觉就是乱搞。。

本来写的最短路。。然后写着写着发现这tm不是一个MST吗……

果断重写 = =


只能从高到低那么就把高的边排前面就行了233

这样每一条边的起点如果可以到达 那么枚举到它的时候它就已经在树里了

然后这题就这么水过去了。。。。


最开始把k打成M = =WA了三次 T_T


#include <cstdio>#include <iostream>#include <queue>#include <cstring> #include <algorithm>using namespace std;const int Nmax = 100005;const int Mmax = 1000005;int N, M;long long ans;int cnt;int H[Nmax];struct ed{    int u, v, w, next;}e[Mmax * 2];int k = 1, head[Nmax];inline void adde(int u, int v, int w){    e[k] = (ed) { u, v, w, head[u] };    head[u] = k++;}queue <int> q;bool vis[Nmax];inline void bfs(){q.push(1); vis[1] = 1; cnt = 1; while(q.size()){int u = q.front(); q.pop();for(int i = head[u]; i; i = e[i].next){int v = e[i].v;if(vis[v]) continue;vis[v] = 1; ++cnt;q.push(v);}}}int fa[Nmax];inline bool cmp(ed a, ed b){if(H[a.v] != H[b.v]) return H[a.v] > H[b.v];return a.w < b.w;}int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }inline void kruskal(){for(int i = 1; i <= N; ++i) fa[i] = i;sort(e + 1, e + k, cmp);for(int i = 1; i < k; ++i){int u = e[i].u, v = e[i].v;if(!vis[u] || !vis[v] || find(u) == find(v)) continue;fa[find(v)] = fa[find(u)]; ans += e[i].w;}}int main(){    scanf("%d%d", &N, &M);    for(int i = 1; i <= N; ++i) scanf("%d", &H[i]);    for(int i = 1; i <= M; ++i)    {        int u, v, w;        scanf("%d%d%d", &u, &v, &w);        if(H[u] >= H[v]) adde(u, v, w);        if(H[v] >= H[u]) adde(v, u, w);    }    bfs(); kruskal();    printf("%d %I64d\n", cnt, ans);        return 0;}



0 0
原创粉丝点击