CC C國有n n n個大城市和m mm 條道路,每條道路連接這 nnn個城市中的某兩個城市。任意兩個城市之間最多只有一條道路直接相連。這 mmm 條道路中有一部分為單向通行的道路,一部分為雙向通行的道路,雙向通行的道路在統計條數時也計為 11 1條。
CC C國幅員遼闊,各地的資源分布情況各不相同,這就導致了同一種商品在不同城市的價格不一定相同。但是,同一種商品在同一個城市的買入價和賣出價始終是相同的。
商人阿龍來到 CCC 國旅游。當他得知同一種商品在不同城市的價格可能會不同這一信息之后,便決定在旅游的同時,利用商品在不同城市中的差價賺回一點旅費。設 CCC 國 n 個城市的標號從 1 n1~ n1 n,阿龍決定從 11 1號城市出發,並最終在 nnn 號城市結束自己的旅行。在旅游的過程中,任何城市可以重復經過多次,但不要求經過所有 nnn 個城市。阿龍通過這樣的貿易方式賺取旅費:他會選擇一個經過的城市買入他最喜歡的商品――水晶球,並在之后經過的另一個城市賣出這個水晶球,用賺取的差價當做旅費。由於阿龍主要是來 CCC 國旅游,他決定這個貿易只進行最多一次,當然,在賺不到差價的情況下他就無需進行貿易。
假設 CC C國有 555個大城市,城市的編號和道路連接情況如下圖,單向箭頭表示這條道路為單向通行,雙向箭頭表示這條道路為雙向通行。
假設 1 n1~n1 n 號城市的水晶球價格分別為 4,3,5,6,14,3,5,6,14,3,5,6,1。
阿龍可以選擇如下一條線路:111->222->333->555,並在 22 2號城市以3 33 的價格買入水晶球,在 333號城市以5 5 5的價格賣出水晶球,賺取的旅費數為 2。
阿龍也可以選擇如下一條線路1 11->444->555->444->555,並在第11 1次到達5 55 號城市時以 11 1的價格買入水晶球,在第 222 次到達4 44 號城市時以6 66 的價格賣出水晶球,賺取的旅費數為5 55。
現在給出 nn n個城市的水晶球價格,mmm 條道路的信息(每條道路所連接的兩個城市的編號以及該條道路的通行情況)。請你告訴阿龍,他最多能賺取多少旅費。
輸入格式:
第一行包含 222 個正整數n n n和 mmm,中間用一個空格隔開,分別表示城市的數目和道路的數目。
第二行 n 個正整數,每兩個整數之間用一個空格隔開,按標號順序分別表示這 n 個城市的商品價格。
接下來 mmm 行,每行有3 3 3個正整數x,y,zx,y,zx,y,z,每兩個整數之間用一個空格隔開。如果 z=1z=1z=1,表示這條道路是城市x x x到城市y y y之間的單向道路;如果z=2 z=2z=2,表示這條道路為城市 xx x和城市yy y之間的雙向道路。
輸出格式:
一 個整數,表示最多能賺取的旅費。如果沒有進行貿易,則輸出 000。
【數據范圍】
輸入數據保證 111 號城市可以到達n n n號城市。
對於 10%的數據,1≤n≤61≤n≤61≤n≤6。
對於 30%的數據,1≤n≤1001≤n≤1001≤n≤100。
對於 50%的數據,不存在一條旅游路線,可以從一個城市出發,再回到這個城市。
對於 100%的數據,1≤n≤1000001≤n≤1000001≤n≤100000,1≤m≤5000001≤m≤5000001≤m≤500000,1≤x1≤x1≤x,y≤ny≤ny≤n,1≤z≤21≤z≤21≤z≤2,1≤1≤1≤各城市
水晶球價格≤100≤100≤100。
NOIP 2009 提高組 第三題
題解:
題目大意就是求出來最大價格差,所以要先求一下在最短路期間的的每一條路上路過的城市的最小值,求完之后還要再求一下每條路上的路過城市的最大值
要注意這個兩次最短路期間求極值的時候我們要一個選擇城市的路徑按題目上給出的,另一個要把存路徑的數組中的道路反過來
為什么要這樣?
正着求一次表示每一次從起點開始的路徑到達這一條路上的某個城市的時候,加上之前經過的這條路上的所有城市中目前價格最低的
反着題目給出的路徑這一種求最大值的最短路,意思是從終點開始的每一條路上,這個城市加上之前經過的這條路上的所有城市中目前價格最高的
這個樣子如果正着路徑經過一個城市,反正路徑也經過了那個城市,那就說明可以從起點中途經過這個點到達終點
最后可以對所有的這些點進行枚舉來找出價格差最大
具體實現看代碼:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 typedef long long ll; 9 const int maxn=100005; 10 const int INF=0x3f3f3f3f; 11 struct shudui 12 { 13 int start; 14 }str1,str2; 15 queue<int>r; 16 int v[maxn],d1[maxn],vis[maxn],n,d2[maxn]; 17 vector<shudui>w[maxn]; 18 vector<shudui>ww[maxn]; 19 void spay(int d[maxn]) 20 { 21 memset(vis,0,sizeof(vis)); 22 23 r.push(1); 24 d[1]=v[1]; 25 vis[1]=1; 26 while(!r.empty()) 27 { 28 int x=r.front(); 29 r.pop(); 30 vis[x]=0; 31 for(int i=0;i<w[x].size();++i) 32 { 33 int y=w[x][i].start; 34 if(d[y]>min(d[x],v[y])) 35 { 36 d[y]=min(d[x],v[y]); 37 if(!vis[y]) 38 { 39 r.push(y); 40 vis[y]=1; 41 } 42 } 43 } 44 } 45 } 46 void spay2(int d[maxn]) 47 { 48 memset(vis,0,sizeof(vis)); 49 r.push(n); 50 d[n]=v[n]; 51 vis[n]=1; 52 while(!r.empty()) 53 { 54 int x=r.front(); 55 r.pop(); 56 vis[x]=0; 57 for(int i=0;i<ww[x].size();++i) 58 { 59 int y=ww[x][i].start; 60 if(d[y]<max(d[x],v[y])) 61 { 62 d[y]=max(d[x],v[y]); 63 if(!vis[y]) 64 { 65 r.push(y); 66 vis[y]=1; 67 } 68 } 69 } 70 } 71 } 72 int main() 73 { 74 int m; 75 scanf("%d%d",&n,&m); 76 for(int i=1;i<=n;++i) 77 scanf("%d",&v[i]); 78 while(m--) 79 { 80 int x,y,z; 81 scanf("%d%d%d",&x,&y,&z); 82 if(z==1) 83 { 84 str2.start=y; 85 w[x].push_back(str2); 86 str2.start=x; 87 ww[y].push_back(str2); 88 } 89 else 90 { 91 str2.start=y; 92 w[x].push_back(str2); 93 str2.start=x; 94 w[y].push_back(str2); 95 str2.start=y; 96 ww[x].push_back(str2); 97 str2.start=x; 98 ww[y].push_back(str2); 99 } 100 } 101 memset(d1,INF,sizeof(d1)); 102 //printf("%d\n",d1[1]); 103 spay(d1); 104 memset(d2,0,sizeof(d2)); 105 spay2(d2); 106 int maxx=0; 107 for(int i=1;i<=n;++i) 108 { 109 //if(d2[i]!=INF && d1[i]!=0) 110 maxx=max(maxx,d2[i]-d1[i]); 111 } 112 printf("%d\n",maxx); 113 return 0; 114 }
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。