善良的国王(最小生成树变形)

问题 C: 善良的国王
时间限制: 1 Sec  内存限制: 128 MB
提交: 112  解决: 48
[提交][状态][讨论版]
题目描述
很久很久以前,有一个贫困的国家,这个国家有一个善良爱民的国王,但是国运维艰,这个国家总是不得不面对这天灾的严峻挑战,又一次连月的大雨,引发了洪水,洪水冲断了道路,水褪去后也有很多村庄成为了孤岛,善良的国王爱民如子,于是他想从本不富足的税收中拿出一部分钱,来给这些村庄修道路,但是国力有限,不能修复所有的道路,于是国王决定,保证村庄两两之间可以到达就好。现在国王想知道他要建的道路中最长的最少要多长。


输入
输入包含多组测试数据,每组测试数据首先输入一个n,表示有n个村庄3 <= n <= 500,编号为1-n,然后下边一个n*n的矩阵,第i行第j列的值,表示标号i到编号j的村庄的距离是这个值,单位1~65536


输出
输出国王要建的道路中最长的最少的长度。


样例输入
3
0 990 692
990 0 179
692 179 0
样例输出
692

提示

//周赛:善良的国王:
//题目大意:
// 国王要给村庄修路,保证每个村庄两两相通 ;求要建的道路中最长的最少要多长。
//解题思路:这题虽不是求最小生成树,但却可以它的的思想去求(逆用克鲁斯卡尔)
//因为要求最长的的道路(即最大生成树)中最短的那条的长度,首先,要找到最长的 ;
//用克鲁斯卡尔找最大生成树只要将 cmp函数的升序改为降序即可,
//这样只要打印这棵树的最后一条路的长度就是答案 ;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 0xfffff
int map[520][520];
int per[520];
int n;
struct node{
	int s;
	int e;
	int len;
}ans[25200];
void init()
{
	int i;
	for(i=1;i<=n;i++)
	  per[i]=i;
}
int cmp(node x,node y)
{
	return x.len>y.len;
}
int find(int a)
{
   int r=a;
   while(r!=per[r])
     r=per[r];
   return r; 
}
bool link (int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy)
	{
		per[fx]=fy;
		return true;
	}
  return false;
}
int main()
{
	int i,j,k,num,cnt,maxl;
	while(scanf("%d",&n)!=EOF)
	{
		k=0;
		memset(map,0,sizeof(map));
		memset(ans,0,sizeof(ans));
		init();
		for(i=1;i<=n;i++)
		  for(j=1;j<=n;j++)
		  {
		  	scanf("%d",&map[i][j]);
		  	if(map[i][j]>0)
		  	{
		  		ans[k].s=i;
		  		ans[k].e=j;
		  		ans[k].len=map[i][j];
		  		k++;
			  }
		  }
		  sort(ans,ans+k,cmp);
		  maxl=M;
		  for(i=0;i<k;i++)
		  {
		  	if(link(ans[i].s,ans[i].e))
		  	{
		  		if(maxl>ans[i].len)
		  		  maxl=ans[i].len;
			  }	
		  }
	 printf("%d\n",maxl);
	}
	return 0;
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bokzmm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值