zoukankan      html  css  js  c++  java
  • 【类克鲁斯卡尔做法+枚举最小边】【HDU1598】【find the most comfortable road】

    题意:
     给你一个图,有边权,K个询问:u到v 的路径中   边权最大值-边权最小值的最小值是多少

    http://acm.hdu.edu.cn/showproblem.php?pid=1598

    题解(非自己想出):把边排序 枚举最小边,然后类似克洛斯卡尔,不断加边 更新ANS值(F[i][j]) 复杂度Q*E^2  
    如果Q变大 可以选择 E*E*N 预处理所有点

    为何我自己没想到?:太拘泥于用深搜的想法去解决,这种跟边权最大值最小值的题目应该多考虑排序边

    解法2:
    二分差值,枚举最小边,再克鲁斯卡尔

    复杂度(Q*log(max-min)*E*E)
    复杂度显然不如 解法1



    代码:
    /*
    WA1:忘记不能到达输出-1
    
    
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    using namespace std;
    struct Edge
    {
        int s,t,w;
    };
    int n,m;
    Edge A[1100];
    int father[300];
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    void input()
    {
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&A[i].s,&A[i].t,&A[i].w);
        }
    }
    void Clear()
    {
         for(int i=1;i<=299;i++)
            father[i]=i;
    }
    bool cmp(Edge a,Edge b)
    {
        return a.w<b.w;
    }
    int find(int x)
    {
        if(x!=father[x])
        father[x]=find(father[x]);
        return father[x];
    }
    void Union(int a,int b)
    {
        int aa=find(a),bb=find(b);
        father[aa]=bb;
    }
    void solve()
    {
        sort(A+1,A+m+1,cmp);
        int Q,u,v;
    
        cin>>Q;
        for(int k=1;k<=Q;k++)
        {
            cin>>u>>v;
            int ok=0;
            int ans=100000000;
            for(int i=1;i<=m;i++)
                {
                    Clear();
                    for(int j=i;j<=m;j++)
                    {
                        Union(A[j].s,A[j].t);
                        if(find(u)==find(v)) {
                                                ans=min(ans,A[j].w-A[i].w);
                                                break;
                                             }
                    }
                }
            if(ans==100000000) printf("-1
    ");
    
            else  printf("%d
    ",ans);
        }
    }
    int main()
    {
       // init();
        while(cin>>n>>m)
        {
            input();
            solve();
        }
    }
    




  • 相关阅读:
    android手机rootROM下载地址
    mysql alter 语句用法,添加、修改、删除字段等
    java比较两个日期大小
    eclipse设置全局编码为UTF-8的方法
    Spring MVC 异步处理请求,提高程序性能
    ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台
    maven之发布项目到nexus【clean deploy命令】
    nexus-3本地下载jar的settipng.xml配置
    windows开启3306端口并用可视化工具访问远程mysql(授权访问)
    mysql 列转行,合并字段
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480398.html
Copyright © 2011-2022 走看看