HDU 2962 Trucking 【二分 + 最短路】

本文介绍了一种结合二分查找与最短路径算法的解决方案,用于解决在一个带有高度限制的图中寻找不超过特定限制高度的最大高度及对应最短路径的问题。通过二分查找确定可行的高度上限,并使用最短路径算法验证该高度是否可达。

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

传送门
// 题意: 给定(n, m)无向图, 每条路上面除了边权还有一个高度, 如果高度为-1那么说明这个无限高. 然后给定一个起点和终点和一个限制高度, 问从起点到终点不超过限制高度的最高高度是多少, 并输出在此高度下的最短路径是多少, 如果不能到达就输出”不能到达”.

// 思路: 很明显的, 每条路上面除了一个边权值还有一个关键字是高度, 那么像这种要求每条边上的某个关键字最大或最小或多少的, 一般都是二分, 所以我们直接二分高度, 然后跑最短路验证ans即可.

AC Code

const int maxn = 1e3+5;
int cas=1;
int cnt, head[maxn];
struct node
{
    int to, next, h, w;
    bool operator < (const node& a) const {
        return w > a.w;
    }
} e[maxn*maxn];

void add(int u, int v,int h ,int w) {
    e[cnt] = (node){v,head[u], h, w};
    head[u] = cnt++;
}

void init() {
    cnt = 0;
    memset(head, -1, sizeof(head));
}

bool vis[maxn];
int dis[maxn];
int dij(int st,int ed, int flag)
{
    priority_queue<node> q;
    Fill(dis,inf); Fill(vis,0);
    dis[st] = 0;
    q.push((node){st, 0, 0, 0});
    while (!q.empty()) {
        node u = q.top();
        q.pop();
        if(vis[u.to]) continue;
        vis[u.to] = 1;

        for (int i = head[u.to]; ~i; i = e[i].next) {
            node k = e[i];
            if (k.h != -1 && k.h < flag) continue;
            if (dis[k.to] > dis[u.to] + k.w) {
                dis[k.to] = dis[u.to] + k.w;
                q.push((node){k.to, 0, 0, dis[k.to]});
            }
        }
    }
    if (dis[ed] == inf) return -1;
    return dis[ed];
}
void solve() {
    int n, m, read = -1;
    while(1) {
        if (read == - 1) scanf("%d%d", &n, &m);
        if (n + m == 0) break;
        init();
        for (int i = 1 ; i <= m ; i ++) {
            int u ,v , h ,w;
            scanf("%d%d%d%d", &u, &v, &h, &w);
            add(u, v, h, w);
            add(v, u, h, w);
        }
        int st, ed, lim;
        scanf("%d%d%d", &st, &ed, &lim);
        int l = 1, r = lim, mid , ans1 = -1, ans2;
        while(r >= l) {
            mid = (l + r) >> 1;
            int tmp = dij(st, ed, mid);
            if (tmp != -1) {
                l = mid + 1;
                ans1 = mid;
                ans2 = tmp;
            }
            else r = mid-1;
        }
        printf("Case %d:\n", cas++);
        if (ans1 == -1) printf("cannot reach destination\n");
        else {
            printf("maximum height = %d\n", ans1);
            printf("length of shortest route = %d\n", ans2);
        }
        scanf("%d%d", &n, &m);
        if (n + m != 0) printf("\n");
        read = 1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值