zoukankan      html  css  js  c++  java
  • 洛谷P1073 最优贸易

    反向建图+dijkstra

    切一道老题水水。。。

    题目的意思是让我们找到两个点x,y,使得差值最大。

    所以我们先在正向图跑dijkstra,用d数组表示从起点到i点的最少价值,所以可以用d[i]=min(w[i], d[j])更新d值

    再用f数组表示从该点到终点的最大价值,这次我们在反向图从n点开始跑dijkstra,这在反向图表示从n到某点的最短路(在正向图即该点到终点的最短路),更新方法与上述类似。
    最后遍历每个点去f[i]-d[i]的最大值即可。

    我开始想用f/d直接更新,d[i]=min(d[i], d[j])。。但是这样有时候得不到正确答案,因为我太弱了,只能想到当图不联通的时候这样是错误的。。。

    因为当某个点与起点或者终点不联通时,按照d[i]=min(d[i], d[j])的方法更新,需要一开始就给所有点的d/f数组附上w的初值,这样以来就变成了d[i]=f[i],最后得出的答案一定是0,但是其实我们在联通的那一部分已经有卖出差价了

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int X = 0, w = 0; char ch = 0;
        while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
        while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
        return w ? -X : X;
    }
    inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
    inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
    template<typename T>
    inline T max(T x, T y, T z){ return max(max(x, y), z); }
    template<typename T>
    inline T min(T x, T y, T z){ return min(min(x, y), z); }
    template<typename A, typename B, typename C>
    inline A fpow(A x, B p, C yql){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % yql)if(p & 1)ans = 1LL * x * ans % yql;
        return ans;
    }
    const int N = 100000;
    int n, m, cnt1, cnt2, head1[N], head2[N], w[N], d[N], f[N];
    bool vis[N];
    struct Edge{
        int v, next;
    }edge1[5*N], edge2[5*N];
    
    void addEdge1(int a, int b){
        edge1[cnt1].v = b;
        edge1[cnt1].next = head1[a];
        head1[a] = cnt1 ++;
    }
    
    void addEdge2(int a, int b){
        edge2[cnt2].v = b;
        edge2[cnt2].next = head2[a];
        head2[a] = cnt2 ++;
    }
    
    void dijkstra_to(){
        memset(d, INF, sizeof d);
        memset(vis, 0, sizeof vis);
        //for(int i = 1; i <= n; i ++) d[i] = w[i];
        priority_queue<pair<int, int>, vector<pair<int, int>>, less<pair<int, int>>> pq;
        d[1] = w[1];
        pq.push(make_pair(d[1], 1));
        while(!pq.empty()){
            int s = pq.top().second, dis = pq.top().first; pq.pop();
            if(vis[s]) continue;
            vis[s] = true;
            for(int i = head1[s]; i != -1; i = edge1[i].next){
                int u = edge1[i].v;
                d[u] = min(dis, w[u]);
                pq.push(make_pair(d[u], u));
            }
        }
    }
    
    void dijkstra_from(){
        memset(f, 0, sizeof f);
        memset(vis, 0, sizeof vis);
        //for(int i = 1; i <= n; i ++) f[i] = w[i];
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
        f[n] = w[n];
        pq.push(make_pair(w[n], n));
        while(!pq.empty()){
            int s = pq.top().second, dis = pq.top().first; pq.pop();
            if(vis[s]) continue;
            vis[s] = true;
            for(int i = head2[s]; i != -1; i = edge2[i].next){
                int u = edge2[i].v;
                f[u] = max(dis, w[u]);
                pq.push(make_pair(f[u], u));
            }
        }
    }
    
    int main(){
    
        memset(head1, -1, sizeof head1);
        memset(head2, -1, sizeof head2);
        n = read(), m = read();
        for(int i = 1; i <= n; i ++) w[i] = read();
        for(int i = 0; i < m; i ++){
            int a = read(), b = read(), c = read();
            if(c == 1) addEdge1(a, b), addEdge2(b, a);
            else if(c == 2) addEdge1(a, b), addEdge1(b, a), addEdge2(a, b), addEdge2(b, a);
        }
        dijkstra_to(), dijkstra_from();
        int ans = 0;
        for(int i = 1; i <= n; i ++)
            ans = max(ans, f[i] - d[i]);
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    socket.io
    CUDA升级后
    QT安装
    windows时钟服务设置
    QT的DPI支持
    cudaDeviceProp结构体
    C#调用C++的dll各种传参
    「LibreOJ#516」DP 一般看规律
    「LibreOJ#515」贪心只能过样例 (暴力+bitset)
    [Codeforces888E]Maximum Subsequence(暴力+meet-in-the-middle)
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/10518868.html
Copyright © 2011-2022 走看看