poj2485:highways(高速公路)(最小生成树算法)
先简单说一下这个题目,就是给你两个城市之间距离,然后你选择修建公路让这些城市必须连通,而且使得所需要修建的公路总长度最短,在你修建的公路当中最长的那个公路输出出来。
我使用的是prim算法。
具体思路是:
先从第一个城市开始,找出距离它最近的城市,在它们之间修建公路,此时这两个城市就已经连通了,通过我设置的变量vis[]将它的值改为1(vis[i]=1表示第i个城市已经连通,vis[i]=0表示第i个城市未连通);然后再找出剩下未连通的城市中与它们俩距离最近的城市之间修建公路…直到所有城市都连通。
首先先将第一个城市到其它城市的距离赋值给lowcost;
在每找出一个新连通的城市的时候通过对比新连通的城市到其他未联通的城市之间的距离来更新lowcost;
将修建的公路存储到b[]数组中,最后找出最长的那条公路;
我的代码中所使用的变量:
a[i][j]:表示第i个城市到第j个城市之间的距离;
ExampleNumber:表示测试用例数;
vis[i]=1:表示第i个城市已经连通;
vis[i]=0:表示第i个城市未连通;
lowcost[i]:表示第i个城市到已连通的城市的距离,若第i个城市已经连通那么设置值为最大值INF;
b[]:该数组存储要修建的公路的长度;
maxx:最终要输出的值;
minn:查找最短距离的中间值;
#include<stdio.h>
#define MAX 500
#define INF 0x3f3f3f3f
int a[MAX][MAX];
int N;
int i;
int j;
int lowcost[MAX];
int vis[MAX];
int ExampleNumber;
int k;
int maxx;
int minn;
int b[MAX];
int main() {
scanf("%d",&ExampleNumber);
while(ExampleNumber--) {
scanf("%d",&N);
for(i=1; i<=N; i++)
for(j=1; j<=N; j++)
scanf("%d",&a[i][j]);
for(i=1; i<=N; i++) {
a[i][i]=INF; //第i个城市自己不能修路,所以设置为最大值
lowcost[i]=a[1][i];
vis[i]=0; //首先将所有城市都设置为未连通
}
vis[1]=1;
//找出距离最近的城市
for(i=1; i<N; i++) {
minn=INF;
for(j=1; j<=N; j++) {
if(minn>lowcost[j]&&vis[j]==0) {
minn=lowcost[j];
k=j;
}
}
vis[k]=1;
b[i]=minn;
//更新lowcost
for(j=1; j<=N; j++) {
if(vis[j]==1) lowcost[j]=INF;
if(vis[j]==0&&a[k][j]<lowcost[j]) {
lowcost[j]=a[k][j];
}
}
}
//找出最长的那个公路
maxx=0;
for(i=1; i<N; i++) {
if(maxx<b[i])
maxx=b[i];
}
printf("%d\n",maxx);
}
}
北大oj上还有一个题目和这个问题比较相似,可以再去练练手
poj1751:highways