【POJ】2485--Highways(最小生成树 --Kruskal)

B - Highways

 POJ - 2485

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.
Input
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.
Output
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.
Sample Input
1

3
0 990 692
990 0 179
692 179 0
Sample Output
692
Hint
Huge input,scanf is recommended.
 思路:

1.先看输入啦,输入是一个n维的矩阵,表示一个点到包括它本身以内的所有点的距离,先用一个二维数组vis[i][j]存起来,i表示起点,j表示终点,vis[i][j]数值就表示i到j点的距离(就是权值啦);然后其实实际需要的只有二维数组中的某些数据就是一个点到另外点的距离,(无向图哦),所以就用到一个循环嵌套,外层for循环i从1到n-1,内层j从i+1到n哟,同时把起点,终点,权值都赋给结构体。到此找到所有两点间的距离,嘿嘿。

2.接下来就是最小生成树的核心(模板,嘿嘿)啦。

#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
	int u,v,dis;
}e[125000+11];
int vis[520][520];
int par[520],ran[520];		//par[]数组表示父结点 ,ran[]数组表示树的高度 
int find(int m)					//找根节点 
{
	if(m==par[m])	//父节点是本身,说明是根节点,返回 
		return m;
	else		//父节点不是本身,查找父节点的父节点 
		return par[m]=find(par[m]);		//递归调用 
}
void unite(int x,int y)			//合并两点 
{
	int fx,fy;
	fx=find(x);
	fy=find(y);
	if(fx==fy)	//两点已经连通,返回 
		return ;
	if(ran[fx]<ran[fy])		//比较两根节点目前所在树的高度 ,低的连在高的上面,一样高则任意一个加一 
		par[fx]=fy;
	else
	{
		par[fy]=fx;
		if(ran[fx]==ran[fy])
			ran[fx]++;
	}
}
bool cmp(node a,node b)		//将权值从小到大排序 
{
	return a.dis <b.dis ;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)	//初始化 
		{
			par[i]=i;
			ran[i]=0;
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				scanf("%d",&vis[i][j]);
			}
		}
		int k=0;
		for(int i=1;i<n;i++)
		{
			for(int j=i+1;j<=n;j++)
			{
				e[k].u=i;
				e[k].v=j;
				e[k].dis=vis[i][j];
				k++;
			}
		}
		sort(e,e+k,cmp);
		int ans=0;
		for(int i=0;i<k;i++)
		{	
			if(find(e[i].u)!=find(e[i].v))		//说明两点原来没有连通 
			{
				ans=max(ans,e[i].dis);		//max()函数在<algorithm>头文件中,可以直接调用哦 
				unite(e[i].u,e[i].v);		//合并两点 
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值