• 【NOIP2009】最优贸易


    题意

    找一条路径上的点p,q,先经过点p,再经过点q,使q-p最大,求这个最大值。

    1≤n≤1000001≤m≤500000

    分析

    其实图论模型和dp模型很类似,一个点到下一个点就是一个状态到下一个状态

    我们考虑正反两次跑一下这个图,正着跑算出b[i]表示到当前点为止访问过的点的最小价值。

    反向加边,算出s[i]表示到当前点为止访问过的点的最大价值。而这个只需要在松弛最短路的时候改一句话就行了。

    最后的答案就是max{s[i]-b[i]}

    MD写迪杰WA半天 向spfa屈服

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200020
    int n,m,cnt,cot,ans;
    int w[N],b[N],s[N],vis[N],first[N],head[N];
    struct email
    {
        int u,v;
        int nxt;
    }e[N*5],g[N*5];
    queue<int>q;
    inline void add1(int u,int v)
    {
        e[++cnt].nxt=first[u];first[u]=cnt;
        e[cnt].u=u;e[cnt].v=v;
    }
    inline void add2(int u,int v)
    {
        g[++cot].nxt=head[u];head[u]=cot;
        g[cot].u=u;g[cot].v=v;
    }
    void spfa()
    {
        memset(b,0x3f,sizeof(b));
        b[1]=w[1];
        q.push(1);vis[1]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();vis[u]=0;    
            for(int i=first[u];i;i=e[i].nxt)
            {
                int v=e[i].v;
                if(b[v]>b[u])
                {
                    b[v]=min(w[v],b[u]);
                    if(!vis[v])q.push(v),vis[v]=1;
                }
                
            }
        }
        memset(vis,0,sizeof(vis));
        s[n]=w[n];
        q.push(n);vis[n]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();vis[u]=0;    
            for(int i=head[u];i;i=g[i].nxt)
            {
                int v=g[i].v;
                if(s[v]<s[u])
                {
                    s[v]=max(w[v],s[u]);
                    if(!vis[v])q.push(v),vis[v]=1;
                }
                
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&w[i]);
        for(int i=1;i<=m;i++)
        {
            int u,v,c;
            scanf("%d%d%d",&u,&v,&c);
            if(c==1)add1(u,v),add2(v,u);
            else
            {
                add1(u,v);add1(v,u);
                add2(u,v);add2(v,u);
            }    
        }
        spfa();
        for(int i=1;i<=n;i++)ans=max(ans,s[i]-b[i]);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    八皇后问题
    Catalan数与出栈顺序个数,Java编程模拟
    推荐系统中的协同过滤
    集成学习
    背包问题
    逆波兰表达式
    [leetcode]775. Global and Local Inversions
    [LeetCode]Minimum Moves to Equal Array Elements1,2
    链接属性
    常用表格属性
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9882073.html
Copyright © 2020-2023  润新知