N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。

输入

第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)

输出

输出最小生成树的所有边的权值之和。

输入样例

9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8

输出样例

37
解:Kruskal算法(排序后添加边)的两种实现(时间消耗差不多):
 #include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef struct Graph
{
int s,e,w;
}graph; int cmp(const void *a,const void *b)
{
return (*(graph *)a).w>(*(graph *)b).w?:-;
} graph p[];
int vis[]; int main()
{
int n,m;
while(scanf_s("%d%d",&n,&m)!=EOF)
{
int i,j,ans=;
memset(vis,,n);
for(i=;i<m;i++) scanf_s("%d%d%d",&p[i].s,&p[i].e,&p[i].w);
qsort(p,m,sizeof(graph),cmp);
vis[p[].s]=;
vis[p[].e]=;
ans+=p[].w;
for(i=;i<n-;i++)
{
for(j=;j<m;j++)
{
if((vis[p[j].s]==&&vis[p[j].e]==)||(vis[p[j].s]&&vis[p[j].e]))
continue;
else
{
vis[p[j].s]=;
vis[p[j].e]=;
ans+=p[j].w;
break;
}
}
}
printf("%d\n",ans);
}
return ;
}
 #include<stdio.h>
#include<stdlib.h>
#include<malloc.h> typedef struct GRAPH
{
int s, e, w;
}graph; int cmp(const void *a, const void *b)
{
return ((graph *)a)->w > ((graph *)b)->w ? : -;
} graph p[];
int *vis[]; int main()
{
int n, m;
while (scanf_s("%d%d", &n, &m) != EOF)
{
int ans = ;
for (int i = ; i < m; ++i) scanf_s("%d%d%d", &p[i].s, &p[i].e, &p[i].w);
qsort(p, m, sizeof(graph), cmp);
for (int i = , j = ; i < m; ++i)
{
int *tmp = (int *)malloc(sizeof(int));
if (vis[p[i].e] == NULL)
{
if (vis[p[i].s] == NULL)
{
*tmp = j++;
vis[p[i].e] = vis[p[i].s] = tmp;
}
else
{
vis[p[i].e] = vis[p[i].s];
free(tmp);
}
}
else if (vis[p[i].s] == NULL)
{
vis[p[i].s] = vis[p[i].e];
free(tmp);
}
else
{
int *a, *b;
for (a = vis[p[i].s]; *a > ; a = *a);
for (b = vis[p[i].e]; *b > ; b = *b);
if (*a == *b)
{
free(tmp);
continue;
}
else
{
*tmp = *a;
*b = *a = tmp;
}
}
ans += p[i].w;
}
printf("%d\n", ans);
}
}

Prim算法(排序后添加点)(写的不好,时间消耗比上面的长):

 #include <stdio.h>
#include <malloc.h>
#include <string.h> #define MIN(a,b) (pt[a]->pr<pt[b]->pr?a:b) typedef struct POINT
{
struct POINT *p;
int ed,pr;
}point; point *pt[];
int vis[][];
int main()
{
int n, m;
while (scanf_s("%d%d", &n, &m) != EOF)
{
int ans = ;
while (m--)
{
int a, b, c;
scanf_s("%d%d%d", &a, &b, &c);
point *tmp1 = (point *)malloc(sizeof(point)), *tmp2 = (point *)malloc(sizeof(point));
tmp1->ed = b;
tmp2->ed = a;
tmp1->pr = tmp2->pr = c;
if (pt[a] == NULL|| tmp1->pr < pt[a]->pr)
{
tmp1->p = pt[a];
pt[a] = tmp1;
}
else for (point *tmp0 = pt[a], *tmp = pt[a]; tmp0 != NULL; tmp = tmp->p)
{
if (tmp == NULL||tmp1->pr < tmp->pr)
{
tmp1->p = tmp0->p;
tmp0->p = tmp1;
break;
}
tmp0 = tmp;
}
if (pt[b] == NULL || tmp2->pr < pt[b]->pr)
{
tmp2->p = pt[b];
pt[b] = tmp2;
}
else for (point *tmp0 = pt[a], *tmp = pt[b]; tmp0 != NULL; tmp = tmp->p)
{
if (tmp == NULL || tmp2->pr < tmp->pr)
{
tmp2->p = tmp0->p;
tmp0->p = tmp2;
break;
}
tmp0 = tmp;
}
}
vis[][] = ;
vis[][] = ;
for (int i = ; i < n; i++)
{
int tmp = ;
for (int j = ; j <= i; j++)
{
if (pt[vis[][j]] == NULL) continue;
else if(vis[][pt[vis[][j]]->ed]!=)
{
if ( == tmp) tmp = vis[][j];
else tmp = MIN(tmp, vis[][j]);
}
else
{
pt[vis[][j]] = pt[vis[][j]]->p;
j--;
}
}
vis[][i+] = pt[tmp]->ed;
vis[][pt[tmp]->ed] = ;
ans += pt[tmp]->pr;
pt[tmp] = pt[tmp]->p;
}
printf("%d\n", ans);
}
}

(图论)51NOD 1212 无向图最小生成树的更多相关文章

  1. 51Nod 1212 无向图最小生成树 (路径压缩)

    N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树.   Input 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N <= 1000, 1 &l ...

  2. 51Nod 1212无向图最小生成树

    prim #include<stdio.h> #include<string.h> #define inf 0x3f3f3f3f ][]; ],lowc[]; ],int n) ...

  3. 51nod 1212 无向图最小生成树(Kruskal模版题)

    N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树.   Input 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N <= 1000, 1 &l ...

  4. 51 nod 1212 无向图最小生成树(Kruckal算法/Prime算法图解)

    1212 无向图最小生成树 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. 收起 输入 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N < ...

  5. 51 nod 1212 无向图最小生成树

    http://www.51nod.com/Challenge/Problem.html#problemId=1212 代码 #include<bits/stdc++.h> using na ...

  6. 51Nod-1212 无向图最小生成树

    51Nod: 1212 无向图最小生成树. link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1212 1212  ...

  7. 51nod1212无向图最小生成树

    1212 无向图最小生成树 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树.   Inpu ...

  8. 无向图最小生成树(prim算法)

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小.该算法于1930年由捷 ...

  9. [matlab] 22.matlab图论实例 最短路问题与最小生成树 (转载)

    最短路问题之 Floyd 某公司在六个城市 c1c1,c2c2,….,c6c6 中有分公司,从 cici 到 cjcj 的直接航程票价记在下述矩阵的 (ii,jj) 位置上. (∞∞表示无直接航路), ...

随机推荐

  1. Ubuntu 16.04安装SQLite Browser操作SQLite数据库

    安装: sudo apt-get install sqlitebrowser 启动:

  2. 如何在不允许联网的环境下使用Maven开发

    前言:Maven的运行机理是:Maven核心组件先去本地的.m2目录下的库中去寻找依赖或者插件,如果本地库里没有,如果配置了私服则上私服去下载依赖或者插件,如果私服上没有,则上中央服务等Maven服务 ...

  3. 聊聊高并发(四十)解析java.util.concurrent各个组件(十六) ThreadPoolExecutor源代码分析

    ThreadPoolExecutor是Executor运行框架最重要的一个实现类.提供了线程池管理和任务管理是两个最主要的能力.这篇通过分析ThreadPoolExecutor的源代码来看看怎样设计和 ...

  4. ffm算法

    www.csie.ntu.edu.tw/~cjlin/papers/ffm.pdf  读书笔记 The effect of feature conjunctions(组合特征) is difficul ...

  5. [Bash] Move and Copy Files and Folders with Bash

    In this lesson we’ll learn how to move and rename files (mv) and copy (cp) them. Move index.html to ...

  6. [RxJS] Implement RxJS `mergeMap` through inner Observables to Subscribe and Pass Values Through

    Understanding sources and subscribers makes it much easier to understand what's going on with mergeM ...

  7. 如何使Linux系统上的程序开机后自动运行 (转)

    Linux有自己一套完整的启动体系,抓住了Linux启动的脉络,Linux的启动过程将不再神秘. 阅读之前建议先看一下附图. 本文中假设inittab中设置的init tree为: /etc/rc.d ...

  8. dotnet new 命令

    如果想知道这个命令的详细用法,可以在打完命令之后,在输入一个" --help"即可 $ dotnet new --help.NET Initializer Usage: dotne ...

  9. url加密并计算时间

    将URL地址参数进行加密传输提高网站安全性 加密算法,直接调用就好 function keyED($txt,$encrypt_key){ $encrypt_key = md5($encrypt_key ...

  10. api多版本方案(URL)

    api多版本方案(URL) 1.利用url https://www.taofen8.com/api/v2/getXXX 2.利用自定义请求头 api-version https://www.taofe ...