zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    致歉
    [公告]博客园正在对网站程序进行性能优化
    [公告]调整默认发布选项
    网站情况继续汇报
    定制“Server Too Busy”错误信息
    可恶的垃圾广告
    博客园分站服务器故障
    很值得期待—SharePoint "V3.0"新特性
    安装Vistual Studio 2005的小问题
    安装智能陈桥五笔时请小心
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3294476.html
Copyright © 2011-2022 走看看