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. 每日一个linux命令(1)

    ls命令: 1.        ls -l -R /home/文件夹   列出/home/文件夹下所有文件和目录的详细资料 2.        ls -l t*                     ...

  2. FIREDAC驱动ORACLE的配置

    1)部署中间件所在的机器必须安装OCI 2)verdorlib,指定OCI所在路径

  3. Office WORD如何为每一页设置不同的页眉页脚

    如下图所示,我想要为封面和目录,摘要等等设置不同的页眉页脚(一般封面和目录不需要页脚)   而从正文开始,套用相同的页眉和以页数作为页脚(注意"第一章 绪论"不是这个文档的第一页) ...

  4. win8 metro 自己写摄像头录像项目

    这是要求不适用CameraCaptureUI等使用系统自带的 camera  UI界面.要求我们自己写调用摄像头摄像的方法,如今我把我的程序贴下: UI界面的程序: <Page x:Class= ...

  5. CDN具体解释(篇二)

    还有还有一个问题就是全部的内容都放在同一个地方.假设我们的server在芝加哥,那么美国中西部的人们訪问server的响应时间和用户体验就比香港.德国.南非以及佛罗里达州的用户好.由于那些用户离ser ...

  6. Linux下怎么添加和查看PATH环境变量

    linux下查看和添加PATH环境变量来自:http://apps.hi.baidu.com/share/detail/32942984 $PATH:决定了shell将到哪些目录中寻找命令或程序,PA ...

  7. 4 Ionic导航和核心组件--旅游应用

    简介:在本节课中,我们将会通过一个虚构的旅游景点来构建一款功能完善的应用.本应用的核心特性是管理用户的应用内导航.本节课的主要目的,是展现构建一个完整的应用的过程. 无论是什么移动应用,最重要的功能之 ...

  8. WEB服务器安装oracle jdbc

    WEB服务器,如果想采用jdbc访问另一台Oracle数据库服务器,那么它应该先安装Oracle客户端,或者要安装oracle jdbc. 那么怎样安装oracle jdbc呢? 1.到oracle下 ...

  9. 【bzoj1965】[Ahoi2005]SHUFFLE 洗牌

    x*2^m==l (mod n+1)x=(n/2+1)^m*l mod n+1 #include<algorithm> #include<iostream> #include& ...

  10. 可以声明接口,但不可以new接口

    接口是一种特殊的抽象类,它包含常量和方法的声明,但没有方法的实现:可以把接口看成是一种特殊的抽象类: 接口实质上是一种规范,它关心的是"做什么",不关心"怎样做" ...