NYOJ 38(最小生成树)

原来是求二维数组的每行或者每列的最小值,不过需要主要的是如果是4个点,只需要3条边就可以完全连接起来了,所以只需要找3次就行了。4条边有一条边会重复,需要舍弃。

就用题目的测试数据比较,用二维数组保存点与点连接的距离。

 

就用i代表行,j代表列。会发现 i,j都是从第二行开始的。而且跟y=x 直线对称。为什么说只要找到每行或者每列的最小值就行了呢。假设最开始没有2这个点,此时1,3,4就是一个集合。然后新添加一个点2进去,此时的最短路径就是点2到这个集合的最短路径,然后看2能够跟集合里面的哪些点连接,测试数据表示能看出来跟1,3,4都连接,所以找出与1,3,4连接的最小值就行,就能够构成一个新的最小生成树。然后比较过一个就标记下,不再重复找,接下来代码就简单了。

//因为每个楼都在最小生成树中,因此无论从哪号楼拉线都没有区别,所以只要选最小那个值就行
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define inf 0x7FFFFFFF/*就是INT_MAX,四个字节,共32位,而每四位为一个十六进制为,因为存在计算机中为补码,所以最高四位是0111,即7*/
int map[501][501];//**二维数组标记地图**//
bool a[501];
int cmp(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}
int main()
{
	int T,m,n;int i,j,k;int min,t,x,y,value,ans;int b[501];//**用一维数组a[i]用来标记第i个点是否被访问过**//
	scanf("%d",&T);
	while(T--)
	{
		memset(b,0,sizeof(b));
		scanf("%d %d",&m,&n);
		ans=0;
		for(i=1;i<=m;i++)
			for(j=1;j<=m;j++)
				map[i][i]=inf;
		for(i=1;i<=n;i++)
		{
			scanf("%d %d %d",&x,&y,&value);
			map[x][y]=map[y][x]=value;//**把能够连接的线都用二维数组保存,并将二维数组赋值**//
		}
		for(i=0;i<m;i++)
			scanf("%d",&b[i]);//**无论从哪号楼拉线都没有区别,所以只要选最小那个值就行**//
		qsort(b,m,sizeof(int),cmp);
		for(i=2;i<=m;i++)
			a[i]=false;
		a[1]=true;//**访问过了,标记true,表示不再访问**//
		for(i=2;i<=m;i++)//**标记了就知道,i,j都是从2开始,并对称**//
		{
			min=inf;
			for(j=2;j<=m;j++)
			{
				if(min>map[i][j]&&!(a[j]==true&&a[i]==true))//**找出最小权值,避免环路**//
				{
					min=map[i][j];
					k=j;
				}
			}
		//	for(j=2;j<=m;j++)//**为下一次循环做准备,重新初始化**//
			//	a[j]=false;
		    a[k]=true;
			if(min!=inf)
				ans=ans+min;//**加上权值**//
			//printf("%d\n",ans);
		}
		printf("%d\n",ans+b[0]);
		system("pause");
	}
	return 0;
}

  

 

时间: 2024-11-08 23:07:40

NYOJ 38(最小生成树)的相关文章

nyoj 925 国王的烦恼(最小生成树)

/* 题意:N个城市中每两个城市有多条路径连接,可是因为路径存在的天数是有限的!以为某条路经不存在了 导致N个城市不能连通了,那么村名们就会抗议!问一共会有多少次抗议! 思路:最小生成树....我们用最大边来建立树!只要有最大边将节点连接并保证连通!那么边权小的值 就可以忽略了!最后将生成树中由(最大边组成的)去重(相同的值只有一次抗议)!这时剩下边的数值就是 答案了! */ #include<iostream> #include<cstring> #include<cstd

【POJ 1679 The Unique MST】最小生成树

无向连通图(无重边),判断最小生成树是否唯一,若唯一求边权和. 分析生成树的生成过程,只有一个圈内出现权值相同的边才会出现权值和相等但"异构"的生成树.(并不一定是最小生成树) 分析贪心策略求最小生成树的过程(贪心地选最短的边来扩充已加入生成树的顶点集合U),发现只有当出现"U中两个不同的点到V-U中同一点的距离同时为当前最短边"时,才会出现"异构"的最小生成树. 上图为kruscal和prim生成过程中可能遇到的相等边的情况,红色和蓝色的为权值

【HDU 4786 Fibonacci Tree】最小生成树

一个由n个顶点m条边(可能有重边)构成的无向图(可能不连通),每条边的权值不是0就是1. 给出n.m和每条边的权值,问是否存在生成树,其边权值和为fibonacci数集合{1,2,3,5,8...}中的一个. 求最小生成树和最大生成树,得到生成树边权和的下界left和上界right.这道题由于每条边权值不是0就是1,因此生成树边权和可以覆盖到[left,right]的每一个数.那么求得[left,right],看是否有fibonacci数在区间内就可以了. 1 #include <cstdio>

【HDU 4463 Outlets】最小生成树(prim,kruscal都可)

以(x,y)坐标的形式给出n个点,修建若干条路使得所有点连通(其中有两个给出的特殊点必须相邻),求所有路的总长度的最小值. 因对所修的路的形状没有限制,所以可看成带权无向完全图,边权值为两点间距离.因是稠密图,故用邻接矩阵存储更好(完全图,边数e达到n(n-1)/2). 至此,可将问题抽象为求最小生成树的边权和. 用了prim+邻接矩阵,prim+邻接表+堆,kruscal各写了一遍,只是内存稍有差别 对于所给的特殊的两个相邻点,只需在开始循环前把这两个点加入子树集合并更新它们所到达的点的min

【UVA 10307 Killing Aliens in Borg Maze】最小生成树, kruscal, bfs

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20846 POJ 3026是同样的题,但是内存要求比较严格,并是没有过... 对以迷宫形式给定的一些点求最小生成树,不过这里的边并不是抽象的两点间笛卡尔距离,也不是折线距离(迷宫中有障碍),而是需要用四个方向的搜索来求. 用bfs求出任两点间的最短距离后,可用kruscal求出最小生成树. 这次值得一提的是对并查集的一点改造:由于每个顶点由一组(x,y)坐标唯一确定

NYOJ 20

  吝啬的国度 时间限制:1000 ms | 内存限制:65535 KB 难度:3   描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设你不走重复的路).   输入 第一行输入一个整数M表示测试数据共有M(1<=M<=5)组每组测试数据的第一行输入一个正整数N(1<=N<=100000)和一个正整数S(1<=S<=100

数据结构-最小生成树的答案错误,求解

问题描述 最小生成树的答案错误,求解 #include #include #define INFINTY 51//不知道怎么定义,才算无穷大 #define MAX_VERTEX_NUM 50 typedef struct { int a[MAX_VERTEX_NUM];//顶点向量 int edges[MAX_VERTEX_NUM[MAX_VERTEX_NUM];//邻接矩阵 int n,;//顶点数 }Graph; int Prim(Graph G){ int *a=(int *)mallo

微软十年反垄断案了结 收16.38亿欧元罚单

欧盟法院驳回了微软要求撤销2008年巨额罚单的申请,但将处罚金额从8.99亿欧元降至8.6亿欧元.这笔巨额罚款缘起于十年前欧盟对微软展开的反垄断调查,微软遭遇多项不正当竞争指控,并被处以重额罚款和责令整改.但由于微软拒不遵守2004年欧盟做出的反垄断决定,欧洲委员会竞争监管机构遂在2008年再次对微软公司处以8.99亿欧元的罚款. [IT商业新闻网综合] (记者 付渑) 6月29日消息,欧盟针对微软公司长达十年的反垄断调查做出最终判决,操作系统霸主将因此支付欧洲反垄断史上的最大罚单--16.38

在图采用邻接表存储时,求最小生成树的Prime算法的时间复杂度为?

问题描述 在图采用邻接表存储时,求最小生成树的Prime算法的时间复杂度为? 在图采用邻接表存储时,求最小生成树的Prime算法的时间复杂度为? A o(n^2) B o(n^3) C o(n) D o(n+e) 答案是o(n+e)...不理解..求过程 解决方案 不对,这题应该选A 求顶点的入度的时间复杂度为O(e)*n=O(n*e) 遍历顶点的时间复杂度是O(n^2) 相加是O(n^2+n*e)=O(n^2) 解决方案二: 详细的解释http://www.cskaoyan.com/redir