zoukankan      html  css  js  c++  java
  • 题解【POJ1797】Heavy Transportation

    题面

    题意简述:

    (n) 个点,(m) 条边,每条边有权值。求一条 (1) 号点到 (n) 号点的路径,要求使得路径中的边权最小值最大。

    ( exttt{Data Range: }1 le n le 1000, 0< w le 10^6。)

    看到最小值最大,直接二分答案。

    二分一个 (mid),只考虑所有边权 (ge mid) 的边,看 (dis_n) 是不是 INF 即可。

    时间复杂度 (O(mlog nlog 10^6))

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    typedef pair <int, int> PII;
    
    inline int gi()
    {
    	int f = 1, x = 0; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return f * x;
    }
    
    const int N = 100003, M = N << 1;
    
    int T;
    int n, m;
    int tot, head[N], ver[M], nxt[M], edge[M];
    int dis[N];
    bool vis[N];
    
    inline void add(int u, int v, int w)
    {
        ver[++tot] = v, edge[tot] = w, nxt[tot] = head[u], head[u] = tot;
    }
    
    void Dij(int x)
    {
        priority_queue <PII> q;
        q.push(make_pair(0, 1));
        memset(vis, 0, sizeof vis);
        memset(dis, 0x3f, sizeof dis);
        while (!q.empty())
        {
            int u = q.top().second; q.pop();
            if (vis[u]) continue; vis[u] = true;
            for (int i = head[u]; i; i = nxt[i])
            {
                int v = ver[i], w = edge[i];
                if (w < x) continue;
                if (dis[v] > min(dis[u], w))
                {
                    dis[v] = min(dis[u], w);
                    q.push(make_pair(-dis[v], v));
                }
            }
        }
    }
    
    inline bool check(int x)
    {
        Dij(x);
        if (dis[n] != 0x3f3f3f3f) return true;
        return false;
    } 
    
    int main()
    {
        T = gi();
        int Case = 0;
        while (T--)
        {
            memset(head, 0, sizeof head);
            tot = 0;
            n = gi(), m = gi();
            int l = 1000001, r = 0;
            for (int i = 1; i <= m; i+=1)
            {
                int u = gi(), v = gi(), w = gi();
                add(u, v, w), add(v, u, w);
                l = min(l, w), r = max(r, w);
            }
            int ans = 0;
            while (l <= r)
            {
                int mid = (l + r) >> 1;
                if (check(mid)) ans = mid, l = mid + 1;
                else r = mid - 1;
            }
            printf("Scenario #%d:
    %d
    
    ", ++Case, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Github for Windows使用介绍
    Activity生命周期
    Java日期LocalDate使用
    一、安装Windows 2012域控(For SQLServer 2014 AlwaysOn)
    .NET(C#):分析IL中的if-else,while和for语句并用Emit实现
    sqlserver中几种典型的等待
    ServiceStack.Redis常用操作
    ServiceStack.Redis 之 IRedisTypedClient<第四篇>
    ServiceStack.Redis之IRedisClient<第三篇>
    Redis常用命令速查 <第二篇>
  • 原文地址:https://www.cnblogs.com/xsl19/p/12891249.html
Copyright © 2011-2022 走看看