Agri-Net

题目描述:

Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course.

Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms.

Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm.

The distance between any two farms will not exceed 100,000.

输入输出格式:

INPUT FORMAT

Line 1:

The number of farms, N (3 <= N <= 100).

Line 2..end:

The subsequent lines contain the N x N connectivity matrix, where each element shows the distance from on farm to another. Logically, they are N lines of N space-separated integers. Physically, they are limited in length to 80 characters, so some lines continue onto others. Of course, the diagonal will be 0, since the distance from farm i to itself is not interesting for this problem.

SAMPLE INPUT (file agrinet.in)

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

OUTPUT FORMAT

The single output contains the integer length that is the sum of the minimum length of fiber required to connect the entire set of farms.

SAMPLE OUTPUT (file agrinet.out)

28

题目大意:

约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000

输入格式

第一行: 农场的个数,N(3<=N<=100)。

第二行..结尾: 后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。

输出格式

只有一个输出,其中包含连接到每个农场的光纤的最小长度。

解题思路:

这个题是一个标准的最小生成树,可以采用kruskal算法构造最小生成树,也可以采用prim算法构造最小生成树,在这里我采用的标准的prim算法来完成这个问题,也是顺便来记录一下prim算法的标准写法,方便日后自己的复习,prim算法的时间复杂度为O(n²),适合求解表稠密的图的最小生成树,相关模板代码如下:

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <set>
#include <cstdio>
#include <algorithm>
#include<cmath>
#include <queue> 
#include<limits.h>
using namespace std;
int n, input[101][101], minn[100001] = {0}, res = 0;
bool f[100001];//标记在生成树中的状态,在为true,不在为false;
int main() {
	for (int i = 0; i < 100001; i++) {
		minn[i] = INT_MAX;
	}
	minn[1] = 0;
	freopen("D:\\test.in", "r", stdin);
	//freopen("D:\\test.out", "w", stdout);
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			scanf("%d", &input[i][j]);
		}
	}
	for (int i = 1; i <= n; i++) {//寻找权值最小的边
		int k = 0;
		for (int j = 1; j <= n; j++) {
			if (!f[j] && minn[j] < minn[k]) {
				k = j;
			}
		}
		f[k] = true;//把k点加入生成树;
		for (int j = 1; j <= n; j++) {//利用新点改变其他不在最小生成树中的点的边的权值 
			if (!f[j] && input[k][j] < minn[j]) {
				minn[j] = input[k][j];
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		res += minn[i];
	}
	printf("%d\n", res);
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值