今天说实话一直都在学习新的知识点。。因为以前就没怎么看最小生成树这一部分,更别说做题了。今天根据题目复习了一下,先是青蛙跳的那道题,不知道咋搞,重新看了看课件,老师以前讲过很多遍,也听懂了,但就是不知道代码咋写,然后找了课件里类似的题琢磨了很长时间。然后做了做第22题,高速公路里第一站到最后一站的最小值问题。。因此学习了prime算法,具体内容详见“最小生成树”的专栏。
然后我还是不懂四色问题,就是没有弄透彻,就是拿到被人称作水题的题。。。我再好好想想吧。
今天感觉prime算法很有趣,在网上找了不少资料才完全理解,好吧,以前真的是太偷懒了。
明天还要接触许多新的东西,我一定要全力以赴,争取把所有题都吃透。我觉得一直都是在学习新知识的过程,还学得慢,不过我不能急躁,踏踏实实的来吧。
所谓最小生成树就是给定一个无向图G = (V, E) 中,G是无向图中所有顶点和边的集合,(u, v) 代表连接顶点 u 与顶点 v 的边,而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集且为无循环图,使得 w(T) 最小,则此 T 为 G 的最小生成树。
而Prime算法就是在无向图中来寻找这样一颗最小生成树。
思想:
1 先选取第一个顶点,然后找出第一个顶点到其他顶点的最小值,然后标记最小值的路径已走过,加入该顶点;2计算现有顶点到其他顶点的最小值,更新最小值列表,找出最小值列表中的最小值,标记路径,加入顶点;3重复以上过程,直到所有顶点都加入;
这个题目就是赤裸裸的Prime算法。以题目中给出的样例来模拟程序执行的过程:
如图所示:先选取1顶点,1顶点到各顶点的最小距离为dis[2]=4,dis[3]=9,dis[4]=21,最小值为4,所以第二个顶点选取顶点2加入,顶点2到顶点3的距离为8<顶点1到顶点3的距离9,所以把9替换为8,即dis[3]=8,同样可替换dis[4]=17,这样下一个加入的顶点为3,然后顶点3到顶点4的距离为16<顶点2到顶点4的距离17,所以dis[4]=16。即为一下过程:
以下是我今天觉得很有价值的一道题。
有关prime算法的:
Highways
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 90 Accepted Submission(s) : 25
Flatopian towns are numbered from 1 to N. Each highway connects exactly two towns. All highways follow straight lines. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways.
The Flatopian government wants to minimize the length of the longest highway to be built. However, they want to guarantee that every town is highway-reachable from every other town.
1 3 0 990 692 990 0 179 692 179 0
692
以下是我的代码:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
int mark[1000];
int map[1000][1000];
int dis[1000];
void Prime(int n)
{
for(int i=0;i<n;i++)
{
mark[i]=0;
dis[i]=map[0][i];//默认第一个坐标为起点
}
mark[0]=1;//表明第一个点进到线内
int p,min=100000,max=0;
for(int i=1;i<n;i++)
{
min=100000;
p=0;
for(int j=0;j<n;j++)
{
if(mark[j]==0&&dis[j]<min)//此点没进到线内,并且此点是距离刚刚存的点距离最小的
{
p=j;//标记新放入的点
min=dis[j];
}
}
mark[p]=1;//标记p点已放入
if(max<min)
max=min;
for(int j=0;j<n;j++)
{
if(mark[j]==0&&dis[j]>map[p][j])
dis[j]=map[p][j];
}
}
cout<<max<<endl;
}
int main()
{
int p;
int n;
memset (map,0,sizeof (map));
scanf("%d",&n);
for (int i = 0; i < n; i++)
{
for( int j = 0; j < n; j++)
{
scanf("%d",&p);
map[i][j]=p;
}
}
Prime (n);
return 0;
}