(图论)51NOD 1212 无向图最小生成树
输入
第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 无向图最小生成树的更多相关文章
- 51Nod 1212 无向图最小生成树 (路径压缩)
N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. Input 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N <= 1000, 1 &l ...
- 51Nod 1212无向图最小生成树
prim #include<stdio.h> #include<string.h> #define inf 0x3f3f3f3f ][]; ],lowc[]; ],int n) ...
- 51nod 1212 无向图最小生成树(Kruskal模版题)
N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. Input 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N <= 1000, 1 &l ...
- 51 nod 1212 无向图最小生成树(Kruckal算法/Prime算法图解)
1212 无向图最小生成树 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. 收起 输入 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N < ...
- 51 nod 1212 无向图最小生成树
http://www.51nod.com/Challenge/Problem.html#problemId=1212 代码 #include<bits/stdc++.h> using na ...
- 51Nod-1212 无向图最小生成树
51Nod: 1212 无向图最小生成树. link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1212 1212 ...
- 51nod1212无向图最小生成树
1212 无向图最小生成树 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. Inpu ...
- 无向图最小生成树(prim算法)
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小.该算法于1930年由捷 ...
- [matlab] 22.matlab图论实例 最短路问题与最小生成树 (转载)
最短路问题之 Floyd 某公司在六个城市 c1c1,c2c2,….,c6c6 中有分公司,从 cici 到 cjcj 的直接航程票价记在下述矩阵的 (ii,jj) 位置上. (∞∞表示无直接航路), ...
随机推荐
- POJ 1724 【存在附加约束的最短路问题】【优先队列】
题意:给K个权值.给含有N个点,R条单向边的图. 每条边都有两个权值,其中一个路长,另外一个是附加权值. 要求路的附加权值之和不超过K的情况下求最短路. 思路: 自己的思路太狭隘,这题还是看了大牛的思 ...
- @Aspect注解无效
Pointcut的execution配置正确的话,检查下,是否加了以下jar包 <!-- http://mvnrepository.com/artifact/org.aspectj/aspect ...
- 扫描仪共享工具(BlindScanner Pro) 3.23 特别版
http://www.xdowns.com/soft/1/126/2014/Soft_125206.html
- json解析bug之ERROR ExceptionController:185 - not close json text, token : :
错误:ERROR ExceptionController:185 - not close json text, token : : 原因:json数据格式有误.!我的错误是,缺少了一个包括json数据 ...
- system表空间用满解决
分类: Oracle 早上看到alert日志报说system表空间快满了(oracle版本是11gR2): 如果system表空间不是自动扩展,空间用满甚至会出现数据库无法登陆.使用任何用户登 ...
- 去哪网实习总结:easyui在JavaWeb中的使用,以datagrid为例(JavaWeb)
本来是以做数据挖掘的目的进去哪网的,结构却成了系统开发. . . 只是还是比較认真的做了三个月.老师非常认同我的工作态度和成果.. . 实习立即就要结束了,总结一下几点之前没有注意过的变成习惯和问题, ...
- Ribbon简介
Ribbon简介
- 容器使用笔记(List篇)
上一篇博客介绍了Dictionary,这篇博客介绍List的相关内容. C#中要存储一组数据.我们会想到数组Array,ArrayList,List这三个对象,当中,数组是最早出现的,我们就从数组開始 ...
- 非计算机专业的伟伯是怎样拿到阿里Offer的。求职励志!!!
写在前面: 2015 年 7 月初.參加阿里巴巴校招内推, 8 月 15 日拿到研发project师 JAVA 的 offer .我的专业并不是计算机,也没有在互联网公司实习过,仅仅有一些学习和面试心 ...
- Linux - Ubuntu中文输入法安装(Ubuntu 12.04)
Ubuntu中文输入法安装(Ubuntu 12.04) 本文地址:http://blog.csdn.net/caroline_wendy Ubuntu作为Linux常见的操作系统,是须要熟练使用的. ...