题目大意:
简而言之,给出一个完全无向图,求其中所有生成树中最大权边最小的值。
输入可能看不懂就是:
第i行 的分别j个数据对应了 i<->j边的权值。
输出这个最大权边最小值。
最小生成树算法。
#include <iostream>
#include <algorithm>
#define N 505
struct Edge
{
int u,v;
int dis;
Edge():u(0),v(0),dis(0){
};
bool operator < (const Edge &a) const
{
return dis<a.dis;
}
}edges[N*N];
using namespace std;
int total=0;
int T,n;
int rank[N];
int father[N];
void MakeSet()
{
for (int i=0;i<n;++i)
{
father[i]=i;
rank[i]=0;
}
}
int find(int x)
{
while(x!=father[x])
x=father[x];
return x;
}
bool Union(int x,int y)
{
int px=find(x);
int py=find(y);
if(px!=py)
{
if(rank[px]>rank[py])
father[py]=px;
else
{
if(rank[px]==rank[py])
rank[py]++;
father[px]=py;
}
return 1;
}
return 0;
}
int Kruskal();
int main()
{
cin>>T;
while(T--)
{
total=0;
scanf("%d",&n);
for (int i=0;i<n;++i)
for (int j=0;j<n;++j)
{
edges[total].u=i;
edges[total].v=j;
scanf("%d",&edges[total].dis);
total++;
}
printf("%d\n",Kruskal());
}
return 0;
}
int Kruskal()
{
MakeSet();
sort(edges,edges+total);
int ans=0;
int cnt=1;
for (int i=0;i<total;++i)
{
int v=edges[i].v;
int u=edges[i].u;
if(Union(v,u))
{
ans=max(ans,edges[i].dis);
cnt++;
}
if(cnt==n)break;
}
return ans;
}
还有一点:!!!!!
第一次我用的是 std::cin, 时间是766Ms
第二次我用的是 scanf() ,时间是250Ms
在输入输出量巨大的时候输入流不能乱用,还是用格式输入输出好了。