51NOD--2609 最苗條的生成樹--生成樹

2609 最苗條的生成樹

  1. 1.0 秒
  2.  
  3. 131,072.0 KB
  4.  
  5. 20 分
  6.  
  7. 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
}*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章