2609 最苗条的生成树
- 1.0 秒
- 131,072.0 KB
- 20 分
- 3级题
定义一颗树的苗条度为这棵树的最大边权与最小边权的差值。
现在有一个n个点m条边的无向联通图,求苗条度最小的生成树的苗条度是多少。
如图所示的数据中:最优的选取方案选取的生成树的三条边分别为(1-4,4-2,1-3),所以答案为100-80=20。
收起
输入
第1行:两个正整数n,m,n表示图中点的个数,m表示图中边的个数。(2<=n<=100,0<=m<=(n*(n − 1)/2)) 第2行-第m+1行:每行3个正整数,u,v,w,表示u和v之间有一条权值为w的边。(1<=u,v<=n,1<=w<=10000)
输出
输出一个整数表示苗条度最小的生成树的苗条度。
输入样例
4 6 1 2 10 1 3 100 1 4 90 2 3 20 2 4 80 3 4 40
输出样例
20
枚举最大最小值。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=20000+66;
const ll mod=1e9+7;
int N,M;
struct node
{
int u;
int v;
int w;
} a[maxn];
bool cmp(const node&a,const node&b)
{
return a.w<b.w;
}
int minn=9999999;
int f[maxn];
int finds(int x)
{
return x==f[x]?x:f[x]=finds(f[x]);
}
void unions(int x,int y)
{
int fx=finds(x);
int fy=finds(y);
if(fx!=fy)
{
f[fx]=fy;
}
}
int work()
{
for(int i=1; i<=N; i++)
f[i]=i;
int flag=0;
for(int i=1; i<=M; i++)
{
int l=a[i].w;
int r=l;
int num=1;
for(int k=1; k<=N; k++)
f[k]=k;
unions(a[i].u,a[i].v);
for(int j=i+1; j<=M; j++)
{
if(finds(a[j].u)!=finds(a[j].v))
{
num++;
unions(a[j].u,a[j].v);
r=max(r,a[j].w);
}
}
if(num==N-1)
{
flag=1;
minn=min(minn,r-l);
}
}
return minn;
}
int main()
{
scanf("%d%d",&N,&M);
for(int i=1; i<=M; i++)
{
scanf("%d %d %d",&a[i].u,&a[i].v,&a[i].w);
}
sort(a+1,a+M+1,cmp);
int ans1=work();
printf("%d\n",ans1);//467 506
}
/*#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=20000+66;
const ll mod=1e9+7;
int N,M;
struct node
{
int u;
int v;
int w;
} a[maxn];
bool cmp(const node&a,const node&b)
{
return a.w<b.w;
}
int minn=9999999;
int f[maxn];
int finds(int x)
{
return x==f[x]?x:f[x]=finds(f[x]);
}
void unions(int x,int y)
{
int fx=finds(x);
int fy=finds(y);
if(fx!=fy)
{
f[fx]=fy;
}
}
int work(int i1,int j1)
{
for(int i=1; i<=N; i++)
f[i]=i;
int num=2;
node x1=a[i1];
node x2=a[j1];
unions(x1.u,x1.v);
unions(x2.u,x2.v);
if(abs(x1.w-x2.w)>minn)return minn;
for(int i=i1; i<=j1; i++)
{
// if(a[i].w<x1.w||a[i].w>x2.w)continue;
if(num==N-1)
break;
if(finds(a[i].u)!=finds(a[i].v))
{
num++;
unions(a[i].u,a[i].v);
}
}
if(num==N-1)
{
minn=abs(x1.w-x2.w);
return abs(x1.w-x2.w);
}
return 9999999;
}
int main()
{
scanf("%d%d",&N,&M);
for(int i=1; i<=M; i++)
{
scanf("%d %d %d",&a[i].u,&a[i].v,&a[i].w);
}
sort(a+1,a+M+1,cmp);
for(int i=1; i<=M; i++)
for(int j=i+1; j<=M; j++)
minn=min(minn,work(i,j));
printf("%d\n",minn);//467 506
}*/