POJ 1258 Agri-Net

题目大意:

        最近农场主约翰被当选为镇长了,他其中第一个竞选承诺就是实现当地各农场之间的网络互连,他起初为自己的农场订购了一批光纤,现在他需要扩大订购将线路分享到其它各个农场,为减小开支,他必须将互联光纤的长度降到最小(前线费用和长度成正比)。

        现有多个测例(测例数无上限),每个测例中都会给出农场数N(3 ≤ N ≤ 100),接着会给出一个N×N的矩阵,给出各农场之间的距离,该距离不会超出100,000,对于每个测例,都需要输出使所有农场可以互联(直接或间接)的最短光纤长度。

题目链接

注释代码:

/*                    
 * Problem ID : POJ 1258 Agri-Net
 * Author     : Lirx.t.Una                    
 * Language   : C++        
 * Run Time   : 0 ms                    
 * Run Memory : 172 KB                    
*/ 

#include <string.h>
#include <stdio.h>

//infinity
//表示总路长最大值
//INF ≥ 单条路径最大值(100,000) × (MAXTOWNN(100)- 1)
#define	INF			10000000

#define	TRUE		1
#define	FALSE		0

//maximum number of towns
//城镇数量的最大值
#define	MAXTOWNN	101

typedef	char		BOOL;

int		d[MAXTOWNN][MAXTOWNN];//d[i],distance bewtween i and j
BOOL	v[MAXTOWNN];//v[i]表示i号镇是否被纳入集合中,即have been visited
int		dp[MAXTOWNN];//dp[j]表示动态规划记录当前集合外的点j到集合内点的最小距离

int
prim(int n) {//Prim求最小生成树
	
	int		i, j;
	int		min, minj;
	int		ans;
	
	//初始化
	dp[1] = 0;
	for ( i = 2; i <= n; i++ )
		dp[i] = d[1][i];
	
	memset( v + 1, FALSE, n * sizeof(BOOL));
	v[1] = TRUE;
	
	//将n个点全部纳入集合后就代表算法成功结束
	for ( ans = 0, i = 2; i <= n; i++ ) {
		
		//找出当前集合外到集合内点最短距离以及该集合外的点
		for ( min = INF, minj = 0, j = 2; j <= n; j++ )
			if ( !v[j] && dp[j] < min ) {
				
				min  = dp[j];
				minj = j;
			}
			
		if ( !minj )//集合外的点到集合内的点都不可达,表示无最小生成树
			return INF;//那么答案自然就是无穷大了
			
		v[minj]  = TRUE;//找到后将其纳入集合
		ans 	+= min;//并动态累加最小生成树的长度
			
		for ( j = 2; j <= n; j++ )//将新点纳入集合后需要利用它更新集合外的点
			                   //到集合内的最短距离
			if ( !v[j] && d[minj][j] < dp[j] )
				dp[j] = d[minj][j];
	}
	
	return ans;
}

int
main() {
	
	int		n;
	int		i, j;
	
	while ( ~scanf("%d", &n) ) {
		
		for ( i = 1; i <= n; i++ )
			for ( j = 1; j <= n; j++ )
				scanf("%d", &d[i][j]);
			
			printf("%d\n", prim(n));
	}
	
	return 0;
}

无注释代码:

#include <string.h>
#include <stdio.h>

#define	INF			10000000
#define	TRUE		1
#define	FALSE		0

#define	MAXTOWNN	101

typedef	char		BOOL;

int		d[MAXTOWNN][MAXTOWNN];
BOOL	v[MAXTOWNN];
int		dp[MAXTOWNN];

int
prim(int n) {
	
	int		i, j;
	int		min, minj;
	int		ans;
	
	dp[1] = 0;
	for ( i = 2; i <= n; i++ )
		dp[i] = d[1][i];
	
	memset( v + 1, FALSE, n * sizeof(BOOL));
	v[1] = TRUE;
	
	for ( ans = 0, i = 2; i <= n; i++ ) {
		
		for ( min = INF, minj = 0, j = 2; j <= n; j++ )
			if ( !v[j] && dp[j] < min ) {
				
				min  = dp[j];
				minj = j;
			}
			
			if ( !minj )
				return INF;
			
			v[minj]  = TRUE;
			ans 	+= min;
			
			for ( j = 2; j <= n; j++ )
				if ( !v[j] && d[minj][j] < dp[j] )
					dp[j] = d[minj][j];
	}
	
	return ans;
}

int
main() {
	
	int		n;
	int		i, j;
	
	while ( ~scanf("%d", &n) ) {
		
		for ( i = 1; i <= n; i++ )
			for ( j = 1; j <= n; j++ )
				scanf("%d", &d[i][j]);
			
			printf("%d\n", prim(n));
	}
	
	return 0;
}

单词解释:

Agri:地名,阿格里(土耳其地区)

elect:vt, 选出,选举出

promise:n, 允诺

connectivity:n, 连通性

order:vt, 订购,订货; n, 订单

lay:vt, 放置,铺设

optical:adj, 光学的

fiber:n, 纤维,光纤

lay optical fiber:n, 铺设光纤

packet:n, 数据包

matrix:n, 矩阵

space-separated:adj, 空格隔开的

diagonal:n, 对角线,斜线; adj, 对角线的,斜的

physically:adv, 身体上地,自然地

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值