zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Java 函数式编程—@FunctionalInterface----functional interface
    人月神话的博客
    如何度量复杂度
    泛型沉思录:创建模版与使用模版生成代码
    ioc与bean管理
    模式(思维)匹配是什么
    简析散光的成因,以及什么是散光的度数和轴位?
    概括是什么?
    思维与模型、世界观
    抽象、维度、层次与分析、综合
  • 原文地址:https://www.cnblogs.com/Ressed/p/9409527.html
Copyright © 2011-2022 走看看