百练之Highway解题报告

1题目

总时间限制:  1000ms 内存限制: 65536kB

描述

The islandnation of Flatopia is perfectly flat. Unfortunately, Flatopia has no publichighways. So the traffic is difficult in Flatopia. The Flatopian government isaware of this problem. They're planning to build some highways so that it willbe possible to drive between any pair of towns without leaving the highwaysystem. 

Flatopian towns are numbered from 1 to N. Each highway connects exactly twotowns. All highways follow straight lines. All highways can be used in bothdirections. Highways can freely cross each other, but a driver can only switchbetween 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 tobe built. However, they want to guarantee that every town is highway-reachablefrom every other town.

输入

The first lineof input is an integer T, which tells how many test cases followed.
The first line of each case is an integer N (3 <= N <= 500), which is thenumber of villages. Then come N lines, the i-th of which contains N integers,and the j-th of these N integers is the distance (the distance should be aninteger within [1, 65536]) between village i and village j. There is an emptyline after each test case.

输出

For each testcase, you should output a line contains an integer, which is the length of thelongest road to be built such that all the villages are connected, and thisvalue is minimum.

样例输入

1

3

0 990 692

990 0 179

692 179 0

样例输出

692

提示

Huge input,scanfis recommended.

2 分析题目

 英文的题目,看着有点头大哈。。。没事,咱们直接看看大意。

有一个地方的政府想给他们的N个村庄修高速公路,公路是支持双向行驶的,那么此时政府测量过每两个村庄的之间的距离之后,提出想要修造的公路满足,任何两个村庄都是可到达的(可以到别的地方借道),也即是没有孤立的村庄,同时因为政府经济。。是吧(哈哈),所以,这公路的总长度是越短越好。并且呢,政府还要知道你要修的公路里最长的那一段。

抽象化一下呗。。也就是说,我们现在有一堆点所形成的无向图,我们需要求解这个最小生成树的最长的权。

由于题目给的是邻接矩阵的图,所以我们直接采用prime算法来做。

3 具体做法

首先我们知道,最小生成树上有整个图上的所有的点。所以,我们以此为突破口。

设定一个Already数组用来存储已经是最小生成树的点

设定一个IsAlready数组用来判断点是不是以及放置在了Already数组中

设定一个lowdis数组用来存储每个剩下的点距离Already数组的最小值

(1)      选定0为起点,将其放置在Already数组里面,标记IsAlready[0]为false

(2)      选定lowdis里的没有放在Already的最小值,将其放置在Already中,标记isAlready为false,并用该最小值和我们想要求的已有最长权Max比较,如果该最小值大,更新Max

(3)      用(2)中获得的值,用该点与其他未进入Already的点的距离,如果该距离大于原来的lowdis[i],更新该lowdis[i]

(4)      重复(2)(3)的操作的,直到Already数组将所有的点存储下来。

(5)      输出Max即可

4代码

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int map[510][510];

int lowdis[510];

int Already[510];

bool IsAlready[510];

int Max;

int n;

void prime()

{

         intct,i;

         intminV,minS;

         //初始化

         memset(IsAlready,true,sizeof(IsAlready));

   Max=0;

         ct=0;

   Already[ct]=0;

         for(i=1;i<n;i++)

         {

      lowdis[i]=map[0][i];

         }

         while(true)

         {

                   if(ct==n-1)

                            break;

                   minV=1<<30;

                   for(i=1;i<n;i++)

                   {

                            if(IsAlready[i]==true&& minV>lowdis[i])

                              {

                                     minV=lowdis[i];

                                     minS=i;

                              }

                   }

                   //入队

                   IsAlready[minS]=false;

                   ct++;

                   Already[ct]=minS;

                   //更新最长边

                   if(minV>Max)

                            Max=minV;

                   //更新距离已有集合数值

                   for(i=0;i<n;i++)

                   {

                            if(IsAlready[i]==true&& map[minS][i]<lowdis[i])

                                     lowdis[i]=map[minS][i];

                   }

         }

}

int main()

{  

         //freopen("in.txt","r",stdin);

         intN;

         inti,j;

         scanf("%d",&N);

         while(N--)

         {

                   scanf("%d",&n);

                   for(i=0;i<n;i++)

                   {

                            for(j=0;j<n;j++)

                              scanf("%d",&map[i][j]);

                   }

          prime();

          printf("%d\n",Max);

         }

         return0;

}

5 收获

首先表明一下,这道题是我们在北京大学暑期学校的组队比赛的时候看到的,我原来只是记得最小生成树的原理,却忘了这个prime算法,于是采取暴力搜索的方式n^2的时间复杂度,果断超时,虽说后来想要用优先队列优化,但是好像不行。于是,很惨的没有做出来。

  8/1的时候,百度了一下,里面说到了用lowdis数组的方式,于是花费30分钟书写出代码A掉了。感觉当时没听课,好伤啊。。。

  最后,我觉得这个东西呢。懂了^v^

发布了16 篇原创文章 · 获赞 2 · 访问量 8892

猜你喜欢

转载自blog.csdn.net/hihei_set/article/details/47378783
今日推荐