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
}*/