luogu1073 最优贸易 (tarjan+dp)
Posted ressed
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu1073 最优贸易 (tarjan+dp)相关的知识,希望对你有一定的参考价值。
tarjan缩点,然后按照拓扑序,做1号点能到达的点的答案
具体做法是对每个点记一个min[i],max[i],vis[i]和ans[i]
做拓扑序的时候,假设在从u点开始做,有边u到v,如果vis[u]=1,则则
vis[v]=1(初始时vis[bel[1]]=1);
更新在v点及以前买进的最小进价:min[v]=min{min[v],min[u]}
统计在v点卖出的答案:ans[v]=max{ans[u],ans[v],max[v]-min[v]}
则最后答案就是ans[bel[N]]
貌似还有做两遍spfa的做法...不管了
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #include<vector> 6 #define LL long long int 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 const int maxn=100010,maxm=1000010; 10 11 LL rd(){ 12 LL x=0;char c=getchar();int neg=1; 13 while(c<‘0‘||c>‘9‘){if(c==‘-‘) neg=-1;c=getchar();} 14 while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar(); 15 return x*neg; 16 } 17 18 int N,M; 19 int eg[maxm][2],egh[maxn],ect; 20 int eg2[maxm][2],egh2[maxn],ect2; 21 int val[maxn],in[maxn],bel[maxn]; 22 int dfn[maxn],low[maxn],stk[maxn],sct,tot,pct; 23 int mi[maxn],ma[maxn],ans[maxn]; 24 vector<int> hav[maxn]; 25 bool instk[maxn],flag[maxn],vis[maxn]; 26 27 inline void adeg(int a,int b){ 28 eg[ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect++; 29 } 30 inline void adeg2(int a,int b){ 31 eg2[ect2][0]=b;eg2[ect2][1]=egh2[a];egh2[a]=ect2++; 32 in[b]++; 33 } 34 35 void tarjan(int x){ 36 dfn[x]=low[x]=++tot;instk[x]=1;stk[++sct]=x; 37 for(int i=egh[x];i!=-1;i=eg[i][1]){ 38 int j=eg[i][0]; 39 if(instk[j]) low[x]=min(low[x],dfn[j]); 40 else if(!dfn[j]) { 41 tarjan(j);low[x]=min(low[x],low[j]); 42 } 43 }if(dfn[x]==low[x]){ 44 pct++;mi[pct]=inf;ma[pct]=-inf; 45 while(sct){ 46 mi[pct]=min(mi[pct],val[stk[sct]]); 47 ma[pct]=max(ma[pct],val[stk[sct]]); 48 bel[stk[sct]]=pct; 49 instk[stk[sct]]=0; 50 hav[pct].push_back(stk[sct]); 51 if(stk[sct--]==x) break; 52 } 53 } 54 } 55 56 57 int main(){ 58 int i,j,k; 59 //freopen("testdata.in","r",stdin); 60 N=rd(),M=rd(); 61 for(i=1;i<=N;i++) val[i]=rd(); 62 memset(egh,-1,sizeof(egh));memset(egh2,-1,sizeof(egh2)); 63 for(i=1;i<=M;i++){ 64 int a=rd(),b=rd(),c=rd(); 65 adeg(a,b);if(c==2) adeg(b,a); 66 }for(i=1;i<=N;i++) if(!dfn[i]) tarjan(i); 67 68 for(i=1;i<=pct;i++){ 69 memset(flag,0,pct+5); 70 for(j=0;j<hav[i].size();j++){ 71 for(k=egh[hav[i][j]];k!=-1;k=eg[k][1]){ 72 if(i==bel[eg[k][0]]) continue; 73 if(!flag[bel[eg[k][0]]]) adeg2(i,bel[eg[k][0]]); 74 flag[bel[eg[k][0]]]=1; 75 } 76 } 77 } 78 queue<int> q;vis[bel[1]]=1; 79 for(i=1;i<=pct;i++){ 80 if(!in[i]) q.push(i); 81 } 82 while(!q.empty()){ 83 int p=q.front();q.pop(); 84 for(i=egh2[p];i!=-1;i=eg2[i][1]){ 85 j=eg2[i][0]; 86 if(vis[p]){ 87 vis[j]=1;ans[j]=max(ans[j],ans[p]); 88 mi[j]=min(mi[j],mi[p]); 89 ans[j]=max(ans[j],ma[j]-mi[j]); 90 } 91 if(!(--in[j])) q.push(j); 92 } 93 } 94 printf("%d ",ans[bel[N]]); 95 }
以上是关于luogu1073 最优贸易 (tarjan+dp)的主要内容,如果未能解决你的问题,请参考以下文章