HDU 1598 find the most comfortable road(枚举+并查集,类似于最小生成树)

一开始想到用BFS,写了之后,发现有点不太行。网上查了一下别人的解法。


首先将边从小到大排序,然后从最小边开始枚举,每次取比它大的边,直到start、end属于同一个集合,即可以连通时停止。
过程类似于最小生成树。舒适感即为选取的最后一条边减去一开始的那条边,所有情况取最小值。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <set>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=211;
const int maxm=1010;
int n,m,q,ans,s,t;

struct Edge{
    int u,v,speed;

    bool operator < (const Edge tmp) const{
        return speed<tmp.speed;
    }
}edge[maxm];

struct UF{
    int father[maxn];
    void init(){
        for(int i=1;i<=n;i++){
            father[i]=i;
        }
    }

    int find_root(int x){
        if(father[x]!=x)
            father[x]=find_root(father[x]);
        return father[x];
    }

    void Union(int a,int b){
        int x=find_root(a);
        int y=find_root(b);
        if(x==y)
            return;
        father[y]=x;
    }
}uf;

int main()
{
    int a,b,c;
    int u,v;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&c);
            edge[i].speed=c;
            edge[i].u=a;
            edge[i].v=b;
        }
        sort(edge+1,edge+m+1);
        scanf("%d",&q);
        for(int w=1;w<=q;w++){
            int i,j;
            ans=INF;
            scanf("%d%d",&s,&t);
            //开始从最小边枚举
            for(i=1;i<=m;i++){
                uf.init();
                //每次取比它大的边
                for(j=i;j<=m;j++){
                    u=edge[j].u;
                    v=edge[j].v;
                    uf.Union(u,v);
                    int x=uf.find_root(s);
                    int y=uf.find_root(t);
                    //若s、t再同一个集合,表明它们之间已构成联通路
                    if(x==y){
                        break;
                    }
                }
                //取完后面所有边,但s、t仍不能连通
                if(j>m)
                    continue;
                //更新最小值
                if(edge[j].speed-edge[i].speed<ans)
                    ans=edge[j].speed-edge[i].speed;
            }
            if(ans<INF)
                printf("%d
",ans);
            else
                printf("-1
");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/chenxiwenruo/p/3294476.html