(图论)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) 位置上. (∞∞表示无直接航路), ...
随机推荐
- [bzoj2780][Spoj8093]Sevenk Love Oimaster_广义后缀自动机
Sevenk Love Oimaster bzoj-2780 Spoj-8093 题目大意:给定$n$个大串和$m$次询问,每次给出一个字符串$s$询问在多少个大串中出现过. 注释:$1\le n\l ...
- IP聚合 ---百度之星(与运算)
Problem Description 当今世界,网络已经无处不在了,小度熊由于犯了错误,当上了度度公司的网络管理员,他手上有大量的 IP列表,小度熊想知道在某个固定的子网掩码下,有多少个网络地址.网 ...
- 洛谷—— P2002 消息扩散
P2002 消息扩散 题目背景 本场比赛第一题,给个简单的吧,这 100 分先拿着. 题目描述 有n个城市,中间有单向道路连接,消息会沿着道路扩散,现在给出n个城市及其之间的道路,问至少需要在几个城市 ...
- hdu6215 Brute Force Sorting(模拟)
题意 给一个长度为n(n<=1e5)的序列,如果一个位置i满足a[i-1]>a[i]或者a[i]>a[i+1],那么我们就称该位置是不合法的位置 先把序列中所有不合法的位置统一找出来 ...
- ntfs格式uefi启动u盘
http://www.laomaotao.org/softhelp/syjc/925.html http://www.laomaotao.org/softhelp/wtjd/989.html http ...
- python爬虫(二)--了解deque
队列-deque 有了上面一节的基础.当然你须要全然掌握上一节的全部方法,由于上一节的方法.在以下的教程中 会重复的用到. 假设你没有记住,请你返回上一节. http://blog.csdn.net/ ...
- js中字符串的拼接的另一种方法
// 按一定长度截断字符串,并使用 + 运算符进行连接. // 分隔字符串尽量按语义进行,如不要在一个完整的名词中间断开. // 特别的,对于HTML片段的拼接,通过缩进,保持和HTML相同的结构. ...
- 【转】TestNG中的并发(多线程)
优势 并行(多线程)技术在软件术语里被定义为软件.操作系统或者程序可以并行地执行另外一段程序中多个部分或者子组件的能力 多线程方式拥有很大的优势: 1). 减少测试运行时间 如果测试集里包含了大量的用 ...
- NoSQL之Redis探析
下载地址:wget http://download.redis.io/releases/redis-2.8.8.tar.gz安装steps:1 下载Official Website : http:// ...
- 菜鸟Sublime日记
一.进行系统安装:www.sublimetext.com/3 选择相应的操作系统,你会发现安装速度惊人的快. 二.安装完成以后,先安装两个基本的插件package control ...