题目大意:
最近农场主约翰被当选为镇长了,他其中第一个竞选承诺就是实现当地各农场之间的网络互连,他起初为自己的农场订购了一批光纤,现在他需要扩大订购将线路分享到其它各个农场,为减小开支,他必须将互联光纤的长度降到最小(前线费用和长度成正比)。
现有多个测例(测例数无上限),每个测例中都会给出农场数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, 身体上地,自然地