zoukankan      html  css  js  c++  java
  • Codevs 1173 最优贸易 2009年NOIP全国联赛提高组

    1173 最优贸易 2009年NOIP全国联赛提高组
    时间限制: 1 s
    空间限制: 128000 KB
    题目等级 : 钻石 Diamond
    题目描述 Description
    【问题描述】
    C 国有n 个大城市和m 条道路,每条道路连接这n 个城市中的某两个城市。任意两个城市之间最多只有一条道路直接相连。这m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道路在统计条数时也计为1 条。
    C 国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。商人阿龙来到 C 国旅游。当他得知同一种商品在不同城市的价格可能会不同这一信息之后,便决定在旅游的同时,利用商品在不同城市中的差价赚回一点旅费。设C 国n 个城市的标号从1~ n,阿龙决定从1 号城市出发,并最终在n 号城市结束自己的旅行。在旅游的过程中,任何城市可以重复经过多次,但不要求经过所有n 个城市。阿龙通过这样的贸易方式赚取旅费:他会选择一个经过的城市买入他最喜欢的商品——水晶球,并在之后经过的另一个城市卖出这个水晶球,用赚取的差价当做旅费。由于阿龙主要是来C 国旅游,他决定这个贸易只进行最多一次,当然,在赚不到差价的情况下他就无需进行贸易。
    假设 C 国有5 个大城市,城市的编号和道路连接情况如下图,单向箭头表示这条道路为单向通行,双向箭头表示这条道路为双向通行。
    假设 1~n 号城市的水晶球价格分别为4,3,5,6,1。
    阿龙可以选择如下一条线路:1->2->3->5,并在2 号城市以3 的价格买入水晶球,在3号城市以5 的价格卖出水晶球,赚取的旅费数为2。
    阿龙也可以选择如下一条线路 1->4->5->4->5,并在第1 次到达5 号城市时以1 的价格买入水晶球,在第2 次到达4 号城市时以6 的价格卖出水晶球,赚取的旅费数为5。现在给出 n 个城市的水晶球价格,m 条道路的信息(每条道路所连接的两个城市的编号以及该条道路的通行情况)。请你告诉阿龙,他最多能赚取多少旅费。
    输入描述 Input Description
    第一行包含 2 个正整数n 和m,中间用一个空格隔开,分别表示城市的数目和道路的数目。
    第二行 n 个正整数,每两个整数之间用一个空格隔开,按标号顺序分别表示这n 个城市的商品价格。
    接下来 m 行,每行有3 个正整数,x,y,z,每两个整数之间用一个空格隔开。如果z=1,表示这条道路是城市x 到城市y 之间的单向道路;如果z=2,表示这条道路为城市x 和城市y 之间的双向道路。
    输出描述 Output Description
    包含1 个整数,表示最多能赚取的旅费。如果没有进行贸易,则输出0。
    样例输入 Sample Input
    5 5
    4 3 5 6 1
    1 2 1
    1 4 1
    2 3 2
    3 5 1
    4 5 2
    样例输出 Sample Output
    5
    数据范围及提示 Data Size & Hint
    【数据范围】
    输入数据保证 1 号城市可以到达n 号城市。
    对于 10%的数据,1≤n≤6。
    对于 30%的数据,1≤n≤100。
    对于 50%的数据,不存在一条旅游路线,可以从一个城市出发,再回到这个城市。
    对于 100%的数据,1≤n≤100000,1≤m≤500000,1≤x,y≤n,1≤z≤2,1≤各城市
    水晶球价格≤100。
    分类标签 Tags
    SPFA 图论 大陆地区 NOIP全国联赛提高组 2009年

    /*
    嗯好题.
    一开始读题得出 
    (1)求1到n的一条有效路径的max-min最大.
    (2)max要在min后面.
    条件(2)比较难搞.
    然后不会orz.
    问了问ylf%%%.
    两边spfa就能保证这个.
    还能顺便求出联通的点处理环的情况.
    正边跑一边min  so dis[i]  表示从1可以到i点的min.
    反边跑一边max  so dis2[i] 表示从n可以到i点的max.
    最后更新答案. 
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<cstring>
    #define MAXN 500001
    using namespace std;
    int dis[MAXN],dis2[MAXN],n,m,tot,cut,head[MAXN],head2[MAXN],w[MAXN],ans;
    bool b[MAXN];
    struct data{int v,next,x;}e[MAXN*2],s[MAXN*2];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v)
    {
        e[++tot].v=v;
        e[tot].next=head[u];
        head[u]=tot;
    }
    void add2(int u,int v)
    {
        s[++cut].v=v;
        s[cut].next=head2[u];
        head2[u]=cut;
    }
    void spfa()
    {
        queue<int>q;q.push(1);b[1]=true;dis[1]=w[1];
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].next)
            {
                dis[e[i].v]=min(dis[e[i].v],min(dis[u],w[e[i].v]));
                if(!b[e[i].v])
                  b[e[i].v]=true,q.push(e[i].v);
            }
        }   
    }
    void spfa2()
    {
        queue<int>q;q.push(n);b[n]=true;dis2[n]=w[n];
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head2[u];i;i=s[i].next)
            {
                dis2[s[i].v]=max(dis2[s[i].v],max(dis2[u],w[s[i].v]));
                if(!b[s[i].v])
                  b[s[i].v]=true,q.push(s[i].v);
            }
        }
    }
    int main()
    {
        memset(dis,127/3,sizeof(dis));
        int x,y,z;
        n=read(),m=read();
        for(int i=1;i<=n;i++)
            w[i]=read();
        for(int i=1;i<=m;i++)
        {
            x=read(),y=read(),z=read();
            if(z==1) add(x,y),add2(y,x);
            else add(x,y),add(y,x),add2(x,y),add2(y,x);
        }
        spfa();memset(b,0,sizeof(b));
        spfa2();
        for(int i=1;i<=n;i++)
          ans=max(ans,dis2[i]-dis[i]);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)
    LeetCode 1041. Robot Bounded In Circle (困于环中的机器人)
    LeetCode 1037. Valid Boomerang (有效的回旋镖)
    LeetCode 1108. Defanging an IP Address (IP 地址无效化)
    LeetCode 704. Binary Search (二分查找)
    LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)
    LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
    LeetCode 817. Linked List Components (链表组件)
    LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)
    29. Divide Two Integers
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070762.html
Copyright © 2011-2022 走看看