luogu P1073 最優貿易
luogu P1073 最優貿易
2017-09-14
題目描述
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 條道路的信息(每條道路所連接的兩個城市的編號以及該條道路的通行情況)。請你告訴阿龍,他最多能賺取多少旅費。
輸入輸出格式
輸入格式:
第一行包含 2 個正整數 n 和 m,中間用一個空格隔開,分別表示城市的數目和道路的數目。
第二行 n 個正整數,每兩個整數之間用一個空格隔開,按標號順序分別表示這 n 個城市的商品價格。
接下來 m 行,每行有 3 個正整數,x,y,z,每兩個整數之間用一個空格隔開。如果 z=1,表示這條道路是城市 x 到城市 y 之間的單向道路;如果 z=2,表示這條道路為城市 x 和城市y 之間的雙向道路。
輸出格式:
輸出文件 trade.out 共 1 行,包含 1 個整數,表示最多能賺取的旅費。如果沒有進行貿易,則輸出 0。
輸入輸出樣例
輸入樣例#1: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。
NOIP 2009 提高組 第三題
正著反著分別做一遍bfs求出所有的在這之前最大最小的買賣的值,ans就是max-min就可以
#include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #include<queue> using namespace std; const int maxn=100000+99; const int INT=(int)1e9+7; int read(){ int an=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();} return an*f; } queue<int>q1; queue<int>q2; int n,m,z,wi[maxn]; int cnt1,cnt2,f1[maxn],f2[maxn]; int ma[maxn],mi[maxn],ans; bool vis1[maxn],vis2[maxn]; struct sabe{ int to,nex; }b1[maxn*6],b2[maxn*6]; void add1(int x,int y){ cnt1++; b1[cnt1].nex=f1[x]; f1[x]=cnt1; b1[cnt1].to=y; } void add2(int x,int y){ cnt2++; b2[cnt2].nex=f2[x]; f2[x]=cnt2; b2[cnt2].to=y; } void bfs1(int x){ q1.push(x);vis1[x]=1;mi[x]=wi[x]; while(!q1.empty()){ int v=q1.front();q1.pop(); for(int i=f1[v];i;i=b1[i].nex){ int u=b1[i].to; mi[u]=min( min(mi[u],mi[v]),wi[u]); if(!vis1[u]){ vis1[u]=1; q1.push(u); } } } } void bfs2(int x){ q2.push(x);vis2[x]=1;ma[x]=wi[x]; while(!q2.empty()){ int v=q2.front();q2.pop(); for(int i=f2[v];i;i=b2[i].nex){ int u=b2[i].to; ma[u]=max( max(ma[v],ma[u]),wi[u] ); if(!vis2[u]){ vis2[u]=1; q2.push(u); } } } } int main(){ for(int i=1;i<=maxn-99;i++)mi[i]=INT; n=read();m=read(); for(int i=1;i<=n;i++)wi[i]=read(); for(int i=1;i<=m;i++){ int x,y; x=read();y=read();z=read(); if(z==1){ add1(x,y); add2(y,x); } else { add1(x,y);add1(y,x); add2(x,y); add2(y,x);} } bfs1(1); bfs2(n); for(int i=1;i<=n;i++)ans=max(ans,ma[i]-mi[i]); cout<<ans; return 0; }bfs
by:s_a_b_e_r
看了樓上一句話應該懂了吧qwq,這題真沒啥好說的……
然而做的時候還是沒想出來……QAQ
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=100009; int n,m,c[N],cnt,tnc,p[N],b[N],mi[N],mx[N]; bool vis[N],siv[N]; struct edge1{ int to,nex; }e1[N<<1]; struct edge{ int to,nex; }e2[N<<1]; queue<int>q,d; void add(int u,int v) { ++cnt; e1[cnt].to=v; e1[cnt].nex=p[u]; p[u]=cnt; } void dda(int u,int v) { ++tnc; e2[tnc].to=v; e2[tnc].nex=b[u]; b[u]=tnc; } void bfs() { q.push(1); mi[1]=c[1]; while(!q.empty()) { int u=q.front();q.pop(); for(int i=p[u];i;i=e1[i].nex) { int v=e1[i].to; mi[v]=min(mi[v],min(mi[u],c[v])); if(!vis[v]){vis[v]=1;q.push(v);} } } } void sfb() { d.push(n); mx[n]=c[n]; while(!d.empty()) { int u=d.front();d.pop(); for(int i=b[u];i;i=e2[i].nex) { int v=e2[i].to; mx[v]=max(mx[v],max(mx[u],c[v])); if(!siv[v]){siv[v]=1;d.push(v);} } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i)scanf("%d",&c[i]); for(int i=1;i<=m;++i) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if(z==1) { add(x,y); dda(y,x); } else { add(x,y);add(y,x); dda(y,x);dda(x,y); } } memset(mi,0x7f7f7f,sizeof(mi)); bfs();sfb(); int ans=0; for(int i=1;i<=n;++i)ans=max(ans,mx[i]-mi[i]); cout<<ans<<endl; return 0; }最優貿易
by:wypx
luogu P1073 最優貿易