(图论)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) 位置上. (∞∞表示无直接航路), ...
随机推荐
- 编译.net .net Core程序 代码,仅做备份
//创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出 //编译.net core项目 var psi = new ProcessStartInfo(&qu ...
- POJ 3230 【DP】
题意: 某货旅行,在n个城市呆m天. 给出从第i个城市到第j个城市的路费,或者留在某个城市的生活费. 给出在第i天在第j个城市的收益. 可以在城市之间任意穿梭逗留没有其他特殊要求. 求收益最大是多少. ...
- Java开发笔记(一百)线程同步synchronized
多个线程一起办事固然能够加快处理速度,但是也带来一个问题:两个线程同时争抢某个资源时该怎么办?看来资源共享的另一面便是资源冲突,正所谓鱼与熊掌不可兼得,系统岂能让多线程这项技术专占好处?果然是有利必有 ...
- Java数组操作方法收集(快速判断某个值在这个数组中)
Java数组操作最高效的方式是循环取值,如果转换成集合那么就会分配内存,效率不如前者,但是方法多,需要在性能调优上去权衡.切记:数组是数组,集合是集合. 下面是收集最常用的数组转成集合的操作方法: i ...
- 信号量学习 & 共享内存同步
刚刚这篇文章学习了共享内存:http://www.cnblogs.com/charlesblc/p/6142139.html 里面也提到了共享内存,自己不进行同步,需要其他手段比如信号量来进行.那么现 ...
- [转]linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结
原文:http://www.jb51.net/LINUXjishu/43356.html ------------------------------------------------------- ...
- Ansible 详细用法说明(二)
setup:获取指定主机的facts. ===================================facts就是变量,内建变量 .每个主机的各种信息,cpu颗数.内存大小等.会存在fact ...
- [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 ...
- [Angular] Expose Angular Component Logic Using State Reducers
A component author has no way of knowing which state changes a consumer will want to override, but s ...
- Office EXCEL 表格如何设置某个单元格是选择项,如何设置一级下拉菜单
1 比如我要在C这一列都做成下拉菜单,则我选中这一列的第一个单元格,然后点击数据-有效性,然后把允许改成"序列",在来源中输入每一项(用逗号隔开),比如我一共要做四个下拉菜单选项, ...