问题 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
时间限制: 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;
}