1. 程式人生 > >1598】 find the most comfortable road

1598】 find the most comfortable road

題目連結:傳送門

題目是一道中文題目,大概題意:給一些雙向邊,多次詢問從起點s,到終點e,(權值max-權值min)的最小值。

本題的正確做法:並查集+思維 (暴力求解,不會超時)      ///並不是最小生成樹

做法:題目求最小值與最大值的差值最小,我們可以將權值從小到大排序,然後列舉最小值,

然後往下開始用並查集,如果起點s和終點e在同一棵樹上了,那麼當前的權值和最小值來更新答案,如果不能構成一棵樹,輸出-1。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

int p[205];

struct node
{
    int s;
    int e;
    int c;

} load[1005];

bool cmp(node a,node b)
{
    return a.c<b.c;
}

int f(int x)
{
    return p[x]==x?x:p[x]=f(p[x]);
}

int main()
{
    int n,m,x,s,e,c;
    while(~scanf("%d %d",&n,&m))
    {
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d %d",&s,&e,&c);
            load[i]=node{s,e,c};
        }
        sort(load+1,load+1+m,cmp);      ///權值排序
        scanf("%d",&x);
        while(x--)
        {
            scanf("%d %d",&s,&e);
            int ans=INT_MAX;
            for(int i=1; i<=m; i++)     ///列舉最小權值
            {
                for(int k=1; k<=n; k++)
                    p[k]=k;
                for(int j=i;j<=m;j++)   ///並查集
                {
                    int q=f(load[j].s),u=f(load[j].e);
                    if(q!=u)
                        p[q]=u;
                    if(f(s)==f(e))  ///如果構成一棵樹了,那麼當前load[j].c就是權值最大。
                    {
                        ans=min(ans,load[j].c-load[i].c);   ///更新答案
                        break;      ///跳出此次列舉,因為已找到此次列舉的最小值
                    }
                }
                if(f(s)!=f(e))
                    break;
            }
            printf("%d\n",ans==INT_MAX?-1:ans);
        }
    }
    return 0;
}