sicily 1090. Highways

// 题意:找出最小生成树的最大边
#include<iostream> //最小生成树Prim算法
using namespace std;
struct MST //最小生成树的边
{
int st,ed,w;
}mst[1000];
int n,edge[1000][1000];
int ans; //ans保存最小生成树的最长边
void Prim()
{
int i,j,k;
for(i=0;i<n-1;i++) //默认选择节点0加入生成树
{
mst[i].st=0;mst[i].ed=i+1;
mst[i].w=edge[0][i+1];
}
for(i=0;i<n-1;++i) //求n-1条边
{
int min_w=100000;
for(j=i;j<n-1;++j)
{
if(mst[j].w<min_w) //求最小权值边
{
min_w=mst[j].w;
k=j;
}
}
swap(mst[k],mst[i]); //最小边移至前端
int v=mst[i].ed;
ans=max(ans,mst[i].w);
for(j=i+1;j<n-1;++j) //更新后面的边
{
int wei=edge[v][mst[j].ed];
if(wei<mst[j].w)
{
mst[j].w=wei;
mst[j].st=v;
}
}
}
}
int main()
{
int cases;
cin>>cases;
while(cases--)
{
cin>>n;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>edge[i][j];
ans=0;
Prim();
cout<<ans<<endl;
if(cases>0)
cout<<endl;
}
return 0;
}




#include <iostream> //最小生成树Kruskal算法
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=520,maxm=125020; //有效总边数是C(500,2)
int n,m; //n,m分别是结点数和边数
int p[maxn]; //记录并查集中该结点的父亲
int u[maxm],v[maxm],w[maxm]; //保存边的端点序号和权值
int r[maxm]; //用于间接排序--排序的关键字是对象的“代号”,而不是对象本身
int cmp(const int i,const int j)
{
return w[i]<w[j];
}
int find(int x)
{
return p[x]==x ? x : p[x]=find(p[x]);
}
int Kruskal()
{
int i,e,x,y;
for(i=0;i<n;++i)
p[i]=i;
for(i=0;i<m;++i)
r[i]=i;
sort(r,r+m,cmp);
int cnt=0;
for(i=0;i<m;++i)
{
e=r[i];
x=find(u[e]);
y=find(v[e]);
if(x!=y)
{
p[x]=y;
cnt++;
if(cnt==n-1)
return w[e]; //最小生成树的最大边
}
}
}
int main()
{
int cases,wei;
scanf("%d",&cases);
while(cases--)
{
scanf("%d",&n);
m=0; //边数
for(int i=0;i<n;++i) //结点下标从0开始
{
for(int j=0;j<n;++j)
{
scanf("%d",&wei);
if(j>i)
{
u[m]=i;
v[m]=j;
w[m]=wei;
m++;
}
}
}
printf("%d\n",Kruskal());
if(cases>0)
printf("\n");
}
return 0;
}

posted on 2011-07-12 16:33  sysu_mjc  阅读(306)  评论(0编辑  收藏  举报

导航