HDU 1879

来源:互联网 发布:程序员必备单词下载 编辑:程序博客网 时间:2024/04/29 05:19

最小生成树,不过有些边是已经有的,有些边是没有的。这里有两种算法,一种是如下采用并查集的方式,另一种是将已经有的边的权值置为0,这样再用Prim或者Kruskal算最小生成树的时候就一定会将这条边选入。


#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;typedef struct Edge {int u, v;int w;int flag;}Edge;Edge e[10005];int p[105];bool cmp(Edge a, Edge b) {return a.w < b.w;}void init(int n) {for(int i = 1; i <= n; i++) {p[i] = i;}}int find(int x) {return p[x] == x ? x : (p[x] = find(p[x]));}int main() {int n, m;while(scanf("%d", &n), n != 0) {int ans;m = n*(n-1)/2;for(int i = 0; i < m; i++) {scanf("%d%d%d%d", &e[i].u, &e[i].v, &e[i].w, &e[i].flag);}sort(e, e+m, cmp);init(n);for(int i = 0; i < m; i++) {if(1 == e[i].flag) {int t1 = find(e[i].u);int t2 = find(e[i].v);if(t1 != t2) {p[t1] = t2;}}}ans = 0;for(int i = 0; i < m; i++) {if(0 == e[i].flag) {int t1 = find(e[i].u);int t2 = find(e[i].v);if(t1 != t2) {p[t1] = t2;ans += e[i].w;}}}printf("%d\n", ans);}return 0;}


原创粉丝点击