soj2198: Highways_Prim
http://acm.scu.edu.cn/soj/problem.action?id=2198
简介题意:输入test测试用例,每个测试用例N个城镇,然后矩阵形式输入各个城镇之间的距离,要求输出使得花费最少的联通各个城镇的最长路径是哪个;
那就是最小生成树呗,输出最小生成树中最大的边长就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 550
#define INF 0x3f3f3f3f
int map[MAX][MAX];
int dist[MAX];
bool visit[MAX];
void prim(int n)
{
bool flag = 1;
memset(visit,0,sizeof(visit));
memset(dist,INF,sizeof(dist));
bool known = 1;
for(int i = 1;i <= n; i++)
if(map[1][i] != 0)
dist[i] = map[1][i];
visit[1] = 1;
int sum = 0;
for(int i = 1;i <= n; i++) //挨个点去visit,选中的visit=1,没选中就一会再看。
{ //就好比说,1一次循环过后,选择了点3,3周围的dist也都知道了,那么我们还是从2点开始看距离
int x;
int minx = INF;
for(int j = 1;j <= n; j++) //i对应的每个点,对应没有visit过的,所有其他点的初始dist
if(!visit[j]&&dist[j]<minx)
{
minx = dist[j];
x = j;
}
if(flag){sum = minx; flag = !flag;} //第一次sum没赋值的时候赋值,以后就不要每次都赋值,否则就覆盖了原来的sum呀
// sum = minx;
if(minx < INF)
{
visit[x] = 1;
//sum += minx; //输出最小生成树的最大边长,我一直以为输出总距离和,幸好重新看题,大家也要仔细审题呀
sum = sum>minx ? sum:minx; //都写了include<algorithm>我还没用max,仿佛一只智障
for(int j = 1;j <= n; j++)
{
if(!visit[j]&&map[x][j]!=0&&map[x][j]<dist[j])
dist[j] = map[x][j]; //对于选中的x=j点,赋值各个dist
}
}
else break;
}
printf("%d\n",sum);
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
for(int j = 1;j <= n; j++)
scanf("%d",&map[i][j]); //因为矩阵形式输入,所以右上三角和左下三角一样,随便你怎么写吧。
prim(n);
}
return 0;
}
感觉就是prim,还没有记录前后连接城镇,所以是最简单的一种题,讲一下Prim的思想吧。
额……我从网上看了一个图解,不能更清晰了,在此把链接附一下,大家也学习学习,主要是分析表啊!!!!特别清晰
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html
他的代码我没有看,但是那个图解真的太好。