POJ_2485 Highway_Prim



2485:Highway

  • 查看
  • 提交
  • 统计
  • 提示
  • 提问
总时间限制: 
1000ms 
内存限制: 
65536kB


The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatopian government is aware of this problem. They're planning to build some highways so that it will be possible to drive between any pair of towns without leaving the highway system. 

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.
输入
The first line of 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 the number 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 an integer within [1, 65536]) between village i and village j. There is an empty line after each test case.
输出
For each test case, you should output a line contains an integer, which is the length of the longest road to be built such that all the villages are connected, and this value is minimum.
样例输入
1

3
0 990 692
990 0 179
692 179 0
样例输出
692
提示

Huge input,scanf is recommended.

#include <iostream>
#include <cstdio>
#include <climits>
#include <cstring>

using namespace std;

#define MAXN 1000
#define NIL 0
#define INF 10000000

class MST
{
public:
	MST(int vertex_num,int edge_num):n(vertex_num),m(edge_num){
		init();
	}
	MST(int vertex_num):n(vertex_num){
		init();
	}
	//采取无向图存储方式
	void Add_Edge(int a, int b, int weight){
		G[a][b] = weight;
		G[b][a] = weight;
	}
	void MST_Prim(int r);		//r - Prim算法的起始点
private:
	void init(){
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++){
				G[i][j] = INF;
			}
	}
	int n;					//点的数量
	int m;					//边的数量
	bool vis[MAXN+4];		//判断点是否被访问过
	int key[MAXN+4];		//到i点边的最小值
	int p[MAXN+4];			//i的祖先结点
	int G[MAXN+4][MAXN+4];
};

void MST::MST_Prim(int r){
	int max = -INF;						//最小生成树--最大边的最小值

	int e;							//结束点--暂存值
	memset(vis,0,sizeof(vis));		//初始化访问数组
	for(int i=1; i<=n; i++){		//初始化距离数组,与祖先数组
		key[i] = INF;
		p[i] = NIL;
	}
	key[r] = 0;
	p[r] = r;

	//对源点初始化到其他顶点的距离,并更新祖先数组
	vis[r] = 1;
	for(int i=1; i<=n; i++){
		if(G[r][i] != INF){
			p[i] = r;
			key[i] = G[r][i];
		}
	}
	for(int i=2; i<=n; i++){
		int min = INT_MAX; 
		key[i] = G[r][i];
	}
	//因为最小生成树只有n-1个边
	for(int i=2; i<=n; i++){
		int min = INT_MAX;
		for(int j=1; j<=n; j++){
			if(key[j]<min && !vis[j]){
				e = j;
				min = key[j];
			}
		}
		vis[e] = 1;
		if(G[p[e]][e] > max)
			max = G[p[e]][e];
		//printf("%d %d %d\n",p[e], e, G[p[e]][e]);
		for(int j=1; j<=n; j++){
			if(G[e][j] < key[j]){
				key[j] = G[e][j];
				p[j] = e;
			}
		}
	}
	printf("%d\n",max);
}

//#define UNSUBMIT
int main(){
#ifdef UNSUBMIT
	freopen("a.in","r",stdin);
#endif
	int T;
	int n;
	int temp;
	int s;					//Prim算法的源点
	MST *t;

	scanf("%d",&T);
	while(T)
	{
		scanf("%d",&n);
		t = new MST(n);
		for(int i=1; i<=n; i++)
		{
			for(int j=1; j<=n; j++)
			{
				scanf("%d",&temp);
				if(temp != 0)
					t->Add_Edge(i,j,temp);
			}
		}
		t->MST_Prim(1);
		T--;
	}

	return 0;
}


你可能感兴趣的:(算法,最小生成树,MST,poj2485)