hdu2962 Trucking

本文介绍了一种使用二分查找法解决含有两个变量同时变化的问题的方法,并通过一个具体的最短路径问题来演示该算法的实现过程。文章提供了一个完整的C++程序代码示例,展示了如何在给定节点间距离和高度限制条件下找到可达终点的最大高度及其对应的最短路径长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算是简单题目, 遇到有两个变量同时变化时,一般的做法是二分一个变量,求另外一个变量。
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int M = 1005;
const int inf = 9999999;

int dist[M][M];
int hight[M][M];
int s, e, maxn, minn, len;
int n, m, ans, Case= 1, mid;

void init() {

    minn = inf;
    ans = -1;
    len = inf;
    for(int i = 1; i <= n; i++) {

        for(int j = 1; j <= n; j++){

            dist[i][j] = inf;
            hight[i][j] = 0;
        }
    }
}

void input() {

    int x, y, h, d;
     for(int i = 0; i < m; i++) {

            scanf("%d%d%d%d", &x, &y, &h, &d);
                dist[x][y] = dist[y][x] = d;
            if(h == -1){
                hight[x][y] = hight[y][x] = inf;

            }else {
                    hight[x][y] = hight[y][x] = h;
            }
            if(h != -1)
            minn = min(h, minn);
        }
    scanf("%d%d%d", &s,&e, &maxn);
    if(Case > 1)
            printf("\n");
}

int Dijstra(int mid) {

    int dis[M];
    int vist[M];
    int index, mmin;
    for(int i = 1; i <= n; i++) {

       if(hight[s][i] >= mid){

            dis[i] = dist[s][i];
        }else {

           dis[i] = inf;
       }
        vist[i] = 0;
    }
    dis[s] = 0;
    vist[s] = 1;
    for(int k = 0; k <= n; k++) {

        mmin = inf;
        for(int i = 1; i <= n; i++) {

            if(!vist[i] &&dis[i] < mmin) {

                mmin = dis[i];
                index = i;
            }
        }
        if(mmin == inf)
            break;
        vist[index] = 1;
        for(int i = 1; i <= n; i++) {

            if(!vist[i] && dis[i] > dis[index] + dist[index][i] && hight[index][i] >= mid) {

                dis[i] = dis[index] + dist[index][i];
            }
        }
    }

   return dis[e];
}

void work() {

    int temp;
     mid = (maxn + minn)/2;
    while(maxn >= minn) {

        temp = Dijstra(mid);
        if(temp != inf){
            ans = mid;
            len = temp;
            minn = mid + 1;

        }else {

            maxn = mid - 1;
        }
         mid = (maxn + minn)/2;
    }

}

void output() {

     printf("Case %d:\n", Case++);
    if(ans != -1) {

   printf("maximum height = %d\n", ans);
   printf("length of shortest route = %d\n", len);

    }else {

        printf("cannot reach destination\n");
    }
}

int main()
{
    while(scanf("%d%d", &n, &m) != EOF && (n || m)) {
        init();
        input();
        work();
        output();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值