hdu 1233还是畅通工程

来源:互联网 发布:大众mirrorlink 软件 编辑:程序博客网 时间:2024/06/08 20:14

prim(普里姆)算法,求最小生成树。,图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点英语Vertex (graph theory),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克英语Vojtěch Jarník发现;并在1957年由美国计算机科学家罗伯特·普里姆英语Robert C. Prim独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。

#include <cstdio>#include <cstring>#define max_t 0x3f3f3f3fconst int maxn = 110;int map[maxn][maxn];int low[maxn];         //保存各路径最小的权值int visited[maxn];      //标记访问过的点int n, m, v;int prim() {    int min, pos;    int sum = 0;        //存储最短路径和    memset(visited, 0, sizeof(visited));    for(int i = 2; i <= n; i++)        low[i] = map[1][i];    visited[1] = 1;    for(int i = 1; i < n; i++) {            //扫描最短路径,加到sum,并且标记该点        min =max_t;        for(int j = 1; j <= n; j++) if(visited[j] == 0&&min > low[j]) {            pos = j;            min = low[j];        }        sum += min;        visited[pos] = 1;        for(int j = 2; j <=n; j++) { //寻找pos相连的最短路径 if(visited[j] == 0&&low[j] > map[pos][j])                low[j] = map[pos][j];        }    }    return sum;}int main() {    int i, k ,j;    while(scanf("%d", &n)&&n) {        memset(map, max_t, sizeof(map));        for(i = 1; i <= n*(n-1)/2; i++) {           scanf("%d%d%d", &j, &k, &v);            map[k][j] = map[j][k] = v;         }         int ans = prim();         printf("%d\n", ans);    }    return 0;}

克鲁斯卡尔算法(Kruskal)

#include <cstdio>#include <algorithm>using namespace std;const int maxn = 5e3;struct kruskal { int first; int end; int value;}edge[maxn];int pre[maxn], son[maxn];int n, m;bool cmp(const kruskal &a, const kruskal &b) { return a.value < b.value;}int search(int x) { return x == pre[x] ? x : search(pre[x]);}bool join(int x, int y) { int root1, root2; root1 = search(x); root2 = search(y); if(root1 == root2) return false; else if(son[root1] >= son[root2]) { pre[root2] = root1; son[root1] += son[root2]; } else { pre[root1] = root2; son[root2] += root1; } return true;}int main() { int t, sum = 0; while(scanf("%d", &t)&&t) { scanf("%d, &n"); m = n * (n-1) / 2; for(int i = 1; i <= n; i++) { pre[i] = i; son[i] = 1; } for(int i = 1; i <= m; i++) scanf("%d%d%d", &edge[i].first, &edge[i].end, &edge[i].value); sort(edge + 1, edge + m +1); for(int i = 1; i <= m; i++) if(join(edge[i].first, edge[i].end)) sum += edge[i].value; printf("%d", sum); sum = 0; } return 0;}

 

0 0