zoukankan      html  css  js  c++  java
  • 6101 最优贸易 (双向spfa)

    描述
    C国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市。任意两个城市之间最多只有一条道路直接相连。这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双向通行的道路在统计条数时也计为1条。
    C国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。
    商人阿龙来到C国旅游。当他得知“同一种商品在不同城市的价格可能会不同”这一信息之后,便决定在旅游的同时,利用商品在不同城市中的差价赚一点旅费。设C国 n 个城市的标号从 1~n,阿龙决定从1号城市出发,并最终在 n 号城市结束自己的旅行。在旅游的过程中,任何城市可以被重复经过多次,但不要求经过所有 n 个城市。
    阿龙通过这样的贸易方式赚取旅费:他会选择一个经过的城市买入他最喜欢的商品——水晶球,并在之后经过的另一个城市卖出这个水晶球,用赚取的差价当做旅费。因为阿龙主要是来C国旅游,他决定这个贸易只进行最多一次,当然,在赚不到差价的情况下他就无需进行贸易。
    现在给出 n 个城市的水晶球价格,m 条道路的信息(每条道路所连接的两个城市的编号以及该条道路的通行情况)。请你告诉阿龙,他最多能赚取多少旅费。
    输入格式
       第一行包含 2 个正整数n 和m,中间用一个空格隔开,分别表示城市的数目和道路的
    数目。
       第二行 n 个正整数,每两个整数之间用一个空格隔开,按标号顺序分别表示这n 个城
    市的商品价格。
       接下来 m 行,每行有3 个正整数,x,y,z,每两个整数之间用一个空格隔开。如果z=1,表示这条道路是城市x 到城市y 之间的单向道路;如果z=2,表示这条道路为城市x 和城市y 之间的双向道路。
    输出格式
    一个整数,表示答案。
    样例输入
    5 5
    4 3 5 6 1
    1 2 1
    1 4 1
    2 3 2
    3 5 1
    4 5 2
    样例输出
    5
    数据范围与约定
    输入数据保证 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。

    思路:我们需要选择一个最小的价值的城市买入,在最大价值城市卖出。

    那么我们起点一定需要可以到达买入城市,正向以起点spfa, d【y】 = min(d【y】,val【y】),

    且能从买入点到卖出点,再到终点,所以反向建图,然后以终点跑一次spfa,dd【y】 = max(dd【y】,val【y】)。

    这样的两条路径,就分别记录了一个点可以到大的最大价值城市,和最小价值城市。

    注意:需要重复更新,也就是一个点更新后需要遍历它的边,然后把能更新的再次加入队列。而且由于后面节点可能比初始节点小,所以不能做到出栈时即是这个点最小值。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef pair<int,int>p;
     5 const int maxn =500005;
     6 int cnt1,cnt2;
     7 struct Node
     8 {
     9     int x,y;
    10     int next;
    11     Node(int x=0,int y=0,int next=0):x(x),y(y),next(next){}
    12 }node[2][maxn],node2[maxn];
    13 int head[2][maxn>>2];
    14 void add(int x,int y)
    15 {
    16     node[0][++cnt1].x = x;
    17     node[0][cnt1].y = y;
    18     node[0][cnt1].next = head[0][x];
    19     head[0][x] = cnt1;
    20 
    21     node[1][++cnt2].x = y;
    22     node[1][cnt2].y = x;
    23     node[1][cnt2].next = head[1][y];
    24     head[1][y] = cnt2;
    25 }
    26 
    27 int n,m;
    28 int value[maxn>>2];
    29 
    30 int dist[2][maxn];
    31 void dijstra(int s,int t)
    32 {
    33     priority_queue<p>que;
    34     while(!que.empty())que.pop();
    35     if(t == 1)que.push(p(value[s],s));
    36     else que.push(p(-value[s],s));
    37     if(t == 0)memset(dist[t],0x3f,sizeof(dist[t]));
    38     else memset(dist[t],0,sizeof(dist[t]));
    39     while(!que.empty())
    40     {
    41         p tmp = que.top();
    42         que.pop();
    43         int x = tmp.second;
    44         if(t == 0 && dist[t][x] <= -tmp.first)continue;
    45         else if(t == 1 && dist[t][x] >= tmp.first)continue;
    46         dist[t][x] = t==0?-tmp.first:tmp.first;
    47         for(int i=head[t][x];i;i=node[t][i].next)
    48         {
    49             int y = node[t][i].y;
    50             if(t ==0 && dist[t][y] > min(dist[t][x],value[y]))
    51             {
    52                 que.push(p(-min(dist[t][x],value[y]),y));
    53             }
    54             else if(t == 1 && dist[t][y] < max(dist[t][x],value[y]))
    55             {
    56                 que.push(p(max(dist[t][x],value[y]),y));
    57             }
    58         }
    59     }
    60 }
    61 
    62 int main()
    63 {
    64     scanf("%d%d",&n,&m);
    65     for(int i=1;i<=n;i++)
    66     {
    67         scanf("%d",&value[i]);
    68     }
    69     for(int i=1;i<=m;i++)
    70     {
    71         int u,v,k;
    72         scanf("%d%d%d",&u,&v,&k);
    73         add(u,v);
    74         if(k != 1)
    75         add(v,u);
    76     }
    77     dijstra(1,0);
    78     dijstra(n,1);
    79     int maxx = 0;
    80     for(int i=1;i<=n;i++)
    81     {
    82         maxx = max(maxx,dist[1][i] - dist[0][i]);
    83     }
    84     printf("%d
    ",maxx);
    85 }
    View Code

    (还有spfa分成图做法,和dp做法.............

  • 相关阅读:
    WebContent的子目录里面的jsp文件无法将数据传递给Servlet
    MVC 与 三层架构
    使用命令行操作MySQL 及 语法
    JDBC
    字符典
    servlet 生命周期
    6 shell内置命令
    5shell中的数组
    4shell中的特殊变量
    3shell命令替换
  • 原文地址:https://www.cnblogs.com/iwannabe/p/10676232.html
Copyright © 2011-2022 走看看