UVA1395 苗条的生成树 Slim Span(最小生成树)

满分做法:

枚举每个边作为生成树的最小边,再进行最小生成树求出最大边,做差比较即可。

#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxm=20007;
int n,m,ans;
int maxx;
int f[maxm]; 
struct node
{
 int x,y,z;
 bool operator < (const node &s) const
 {
  return z<s.z;	
 }
}t[maxm];
int find(int x)
{
 if(x!=f[x])
 f[x]=find(f[x]);
 return f[x];	
}
bool check(int id)
{
  for(int i=1;i<=n;i++)
  f[i]=i;
  maxx=-1;
  int cnt=0;
  for(int i=id;i<=m;i++)
  {
    int fx=find(t[i].x);
    int fy=find(t[i].y);
    if(fx!=fy)
    {
     f[fx]=fy;
     maxx=t[i].z;
	 cnt++;
	 if(cnt==n-1)
	 return 1;
    }
  }
  return 0;
}
int main()
{
 while(scanf("%d%d",&n,&m))
 {
   if(n==0&&m==0) break;
   for(int i=1;i<=m;i++)
   scanf("%d%d%d",&t[i].x,&t[i].y,&t[i].z);
   for(int i=1;i<=n;i++)
   f[i]=i;
   sort(t+1,t+m+1);
   ans=998244353;
   for(int i=1;i<=m-n+2;i++)//如果剩下的边不足n-1 
   {
   	 if(check(i))//枚举最小边,进行最小生成树 
   	 {
   	   	ans=min(ans,maxx-t[i].z);
   	 }
   }
   if(ans==998244353)
   printf("-1
");
   else
   printf("%d
",ans); 
 }
 return 0;	
}
原文地址:https://www.cnblogs.com/lihan123/p/11686511.html