zoukankan      html  css  js  c++  java
  • HDU 2363 Cycling (最短路 + 暴力枚举)

    给与n座山头m条路,求高度差最小的前提下的最短路。。

    用dijkstra记录上个节点最高最低点/二分上下界 WA了一辈子,最后发现数据规模其实很小。

    直接枚举每一个上下界得到结果即可。

    双向边,双向边,双向边。

    #include <algorithm>
    #include <queue>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define inf 0x3fffffff
    #define N 105
    using namespace std;
    typedef long long ll;
    struct e{
        int to,dis,next;
    }edge[N*N];
    int head[N],cnt,h[N];
    int dis[N];
    void init(){
        memset(head,-1, sizeof(head));
        cnt = 0;
    }
    void add(int u,int v ,int d){
        edge[cnt].to = v;
        edge[cnt].next = head[u];
        edge[cnt].dis = d;
        head[u] = cnt++;
    }
    
    struct node{
        int first;
        int second;
        node (int a = 0,int b = 0):first(a),second(b){}
        bool operator < (const node &X)const{
            return first>X.first;
        }
    };
    int n;
    priority_queue<node>ss;
    bool dijkstra(int st,int mins,int maxs){
        while (!ss.empty())ss.pop();
        int u,v;
        if(h[st] > maxs || h[st] < mins || h[n] > maxs || h[n] < mins)return false;
        for(int i = 0 ; i <= n ; ++i)dis[i] = inf;
        dis[st] = 0;
        ss.emplace(node(dis[st],st));
        while (!ss.empty()){
            u = ss.top().second;
            ss.pop();
            if(h[u] > maxs || h[u] < mins )continue;
            for(int i = head[u]; ~i ; i = edge[i].next){
                v = edge[i].to;
                if(h[v] > maxs || h[v] < mins)continue;
                if(dis[v] > dis[u] + edge[i].dis){
                    dis[v] = dis[u] + edge[i].dis;
                    ss.emplace(node(dis[v],v));
                }
            }
        }
        return dis[n]!=inf;
    }
    pair<int,int>deal[N*N];
    bool cmp(const pair<int,int>&a,const pair<int,int>&b){
        return (a.first-a.second ) < ( b.first-b.second);
    }
    int main(){
        int t,m,a,b,d;
        cin>>t;
        for(int k = 1 ; k <= t ; ++k){
            cin>>n>>m;
            init();
            for(int j = 1 ; j <= n ; ++j){
                scanf("%d",h+j);
            }
            while (m--){
                scanf("%d %d %d",&a,&b,&d);
                add(a,b,d);
                add(b,a,d);
            }
            int count = 0;
            for(int i = 1 ; i <= n ; ++i){
                for(int j = i ; j <= n ; ++j){
                    deal[count].first = max(h[i],h[j]);
                    deal[count++].second = min(h[i],h[j]);
                }
            }
            sort(deal,deal+count,cmp);
            int i;
            for(i = 0 ; i < count ; ++i){
                if(dijkstra(1,deal[i].second,deal[i].first)){
                    break;
                }
            }
            printf("%d %d
    ",deal[i].first - deal[i].second,dis[n]);
        }
    }
  • 相关阅读:
    pl/sql 编程!
    oracle中的常用函数、字符串函数、数值类型函数、日期函数,聚合函数。
    oracle 相关查询和非相关查询,oracle 去除重复数据,以及oracle的分页查询!
    初识 oracle!
    分页查询。
    利用ajax技术 实现用户注册。
    quartz CronExpression
    SQL 面试题
    什么是HTTP协议?常用的状态码有哪些?
    聚集索引与非聚集索引
  • 原文地址:https://www.cnblogs.com/DevilInChina/p/9411132.html
Copyright © 2011-2022 走看看