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

     最优贸易
    (trade.pas/c/cpp)
    【问题描述】
    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条道路的信息(每条道路所连接的两个城市的编号
    以及该条道路的通行情况)。请你告诉阿龙,他最多能赚钱多少旅费。
     
    【输入】
    输入文件名为trade.in。
    第一行包含 2 个正整数 n 和 m,中间用一个空格隔开,分别表示城市的数目和道路的
    数目。
    第二行 n 个正整数,每两个正整数之间用一个空格隔开,按标号顺序分别表示这 n 个
    城市的商品价格。
    接下来 m行,每行有 3 个正整数, x,y,z,每两个整数之间用一个空格隔开。如果z=1,
    表示这条道路是城市x到城市 y之间的单向道路;如果 z=2,表示这条道路为城市x 和城市

    y之间的双向道路。
     
    【输出】
    输出文件 trade.out 共 1 行,包含 1 个整数,表示最多能赚取的旅费。
    易,则输出0。
     
    【输出输出样例】
    trade.in trade.out
    5 5
    4 3 6 5 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,先用一次SPFA 求出最大水晶球价格和最低价格,在将边反向,求出最大差(为了使阿龙能到达终点。)

      1 #include <iostream>
      2 #include <fstream>
      3 #include <cstdlib>
      4 #include <cstring>
      5 using namespace std;
      6 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
      7 ifstream fin("trade.in");
      8 ofstream fout("trade.out");
      9 
     10 int cnt_city=0,cnt_rode=0;
     11 int city_jia[100005]={0};
     12 int shun_tou[100005]={0},shun_cnt=0;
     13 int ni_tou[100005]={0},ni_cnt=0;
     14 struct tu{
     15  int nxt;
     16  int to;    
     17 };
     18  tu shunxu[500005]={0};
     19  tu nixu[500005]={0};
     20 int zx_jia[100005]={0};
     21 int zd_jia[100005]={0}; 
     22 int dui[1000005]={0}; 
     23 bool zai[500005]={0};
     24 
     25 void add(int a,int b );
     26 void zadd(int a,int b);
     27 void spfa_shun(      );
     28 void spfa_ni( );
     29 void output( );
     30 
     31 void add(int a,int b){
     32  shunxu[++shun_cnt].nxt=shun_tou[a];
     33  shunxu[shun_cnt].to=b;
     34  shun_tou[a]=shun_cnt;
     35  return;
     36 }
     37 
     38 
     39 void zadd(int a,int b){
     40  nixu[++ni_cnt].nxt=ni_tou[a];
     41  nixu[ni_cnt].to=b;
     42  ni_tou[a]=ni_cnt;
     43  return;         
     44 }
     45 
     46 
     47 void spfa_shun( ){
     48  int head=0,tail=1;    
     49  dui[1]=1,zx_jia[1]=city_jia[1],zd_jia[1]=city_jia[1];
     50  zai[1]=1;
     51  do{
     52   head++;
     53   if(head>1000003)head=1;
     54   int cong=dui[head];
     55   for(int hao=shun_tou[cong];hao!=-1;hao=shunxu[hao].nxt){
     56    int dao=shunxu[hao].to;
     57    int xiao=min(zx_jia[cong],city_jia[dao]);
     58    if(xiao<zx_jia[dao]){
     59        zx_jia[dao]=xiao;
     60        if(zai[dao]==0){
     61         tail++;
     62         if(tail>1000003)tail=1;
     63      dui[tail]=dao;    
     64      zai[dao]=1;       
     65     }
     66    }    
     67    
     68   }
     69   zai[cong]=0;
     70  }while(head!=tail);    
     71  return;    
     72 }
     73 
     74 
     75 void spfa_ni( ){
     76  memset(dui,0,sizeof(dui));
     77  memset(zai,0,sizeof(zai));
     78  int head=0,tail=1;    
     79  dui[1]=cnt_city;
     80  zai[cnt_city]=1;
     81  do{
     82   head++;
     83   if(head>1000003)head=1;
     84   int cong=dui[head];
     85   for(int hao=ni_tou[cong];hao!=-1;hao=nixu[hao].nxt){
     86    int dao=nixu[hao].to;
     87    int da=max(zd_jia[cong],city_jia[dao]);
     88    if(da>zd_jia[dao]){
     89        zd_jia[dao]=da;
     90         tail++;
     91         if(tail>1000003)tail=1;
     92      dui[tail]=dao;    
     93      zai[dao]=1;       
     94     
     95    } 
     96    if(zai[dao]==0){
     97        zai[dao]=1;
     98     tail++;
     99     if(tail>1000003)tail=1;
    100     dui[tail]=dao;    
    101    } 
    102   }
    103  }while(head!=tail);    
    104  return;    
    105 }
    106 
    107 
    108 void output( ){
    109  int max_mon=0;    
    110  for(int x=1;x<=cnt_city;x++){
    111   //cout<<zd_jia[x]<<" "<<zx_jia[x]<<endl;
    112   if(zai[x]==1)    
    113   max_mon=max(max_mon,zd_jia[x]-zx_jia[x]);    
    114  }    
    115  cout<<max_mon;    
    116  fout<<max_mon;    
    117 }
    118 
    119 
    120 int main(int argc, char *argv[]){
    121  fin>>cnt_city>>cnt_rode;
    122  for(int x=1;x<=cnt_city;x++)fin>>city_jia[x];
    123  memset(shun_tou,-1,sizeof(shun_tou));
    124  memset(ni_tou,-1,sizeof(ni_tou));
    125  for(int x=1;x<=cnt_rode;x++){
    126   int a,b,c;
    127   fin>>a>>b>>c;
    128   add(a,b);
    129   zadd(b,a);
    130   if(c==2){
    131    add(b,a);
    132    zadd(a,b);
    133   }
    134  }
    135 
    136  memset(zx_jia,0x7f,sizeof(zx_jia));
    137  memset(zd_jia,-1,sizeof(zd_jia));
    138  spfa_shun( );  
    139  spfa_ni( );
    140  
    141  output( );
    142  
    143  return 0;
    144 }
  • 相关阅读:
    Object类学习
    Thread.State 线程状态
    Thread.UncaughtExceptionHandler
    apply和call的区别
    如何实现border-width:0.5px;
    table固定头部,表格tbody可上下左右滑动
    canvas画布实现手写签名效果
    ES6学习笔记
    for循环中执行setTimeout问题
    javaScript函数提升及作用域
  • 原文地址:https://www.cnblogs.com/Ateisti/p/4805056.html
Copyright © 2011-2022 走看看