• P1073 最优贸易 详细过程


    怎么想

    模拟样例数据之后猜想:从1开始走,记着最低价格,往后一直走,不断更新差价。

    但这样碰到环就麻烦了。

    所以考虑缩点,DAG图能省去一些麻烦。

    阿龙要低价买入,高价卖出,而每条路可以反复地走,

    那么在一个强连通分量中,阿龙一定可以在该强连通分量中售价最低处买入,最高处卖出。

    可以从1所在的强连通分量开始,往后走,并记录可以买到货物的最低价格,到达一个新城市群(强连通分量)

    就比较当前差价是否比之前找到的差价更大。

    具体怎么实现呢,

    我们可以用ccnt,vheadp[ ] ,ve[ ] 这些建一个SCC图,然后在图上跑dfs

    提交!


    还好不是考场,还好不是MLE,TLE,之类的

    下波数据看看:发现标答是2,输出了99

    事情似乎明了了

    需要注意的地方


    答案偏大了,说明我们可能把不满足条件的城市也加进来了

    为什么说是不满足条件的呢?

       “读题呀,一定要仔细。”--化学老师

    题目告诉我们:阿龙虽然需要在路上赚些生活费,但他的最终目的是终点n

    而输入的图中,从某些点出发是不能到达终点的

    所以我们构造反图,筛选一波。

    再提交

     NICE

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stack>
    #define FOR(i,n) for(register int i=1;i<=n;i++)
    using namespace std;
    const int N=100005;
    struct NODE{
        int v,nxt;
    };
    NODE e[N*9],ve[N*9],ne[N*9];
    int head[N],vhead[N],pmin[N],pmax[N],cmin[N],cmax[N],color[N],dfn[N],ins[N],low[N];
    int nhead[N],ntot;
    bool nvis[N];
    int n,m,colorcnt,tot,vtot,timing,ans;
    stack <int> s;
    void add(int u,int v)
    {e[++tot].v=v;e[tot].nxt=head[u];head[u]=tot;}
    void vadd(int u,int v)
    {ve[++vtot].v=v;ve[vtot].nxt=vhead[u];vhead[u]=vtot;}
    void nadd(int u,int v){ne[++ntot].v=v;ne[ntot].nxt=nhead[u];nhead[u]=ntot;}
    void tarjan(int u)
    {
        ins[u]=1;
        dfn[u]=low[u]=++timing;
        s.push(u);
        for(int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(ins[v])
                 low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u])
        {    
            colorcnt++;
            cmin[colorcnt]=1e8;
            int tmp=s.top();
            while(tmp!=u)
            {
                cmin[colorcnt]=min(cmin[colorcnt],pmin[tmp]);
                cmax[colorcnt]=max(cmax[colorcnt],pmax[tmp]);
                s.pop();
                ins[tmp]=0;
                color[tmp]=colorcnt;
                tmp=s.top();
                
            }
            ins[u]=0;color[u]=colorcnt;s.pop();
            cmin[colorcnt]=min(cmin[colorcnt],pmin[u]);
            cmax[colorcnt]=max(cmax[colorcnt],pmax[u]);
        }
    }
    void dfs2(int nt)
    {
        if(nvis[nt]) return;
        nvis[nt]=1;
        for(int i=nhead[nt];i;i=ne[i].nxt)
            dfs2(ne[i].v);
    }
    void get_ans(int ccnt,int mini)
    {
        if(ins[ccnt]||!nvis[ccnt]) return;
        ins[ccnt]=1;
        ans=max(ans,cmax[ccnt]-mini);
        for(int i=vhead[ccnt];i;i=ve[i].nxt)
        {
            int v=ve[i].v;
            get_ans(v,min(mini,cmin[v]));
        }
    }
    int main()
    { 
        //freopen("in.in","r",stdin);
        //freopen("out.out","w",stdout);
        scanf("%d%d",&n,&m);
        int a,b,c;
        FOR(i,n) cin>>pmin[i],pmax[i]=pmin[i];
        FOR(i,m)
        {
            cin>>a>>b>>c;
            add(a,b);
            if(c==2) add(b,a);
        }
        FOR(i,n)
        if(!dfn[i])
        tarjan(i);
        FOR(i,n)   
        {
            for(int j=head[i];j;j=e[j].nxt)
            {
                int v=e[j].v;
                if(color[v]!=color[i])
                {
                    vadd(color[i],color[v]);
                    nadd(color[v],color[i]);
                }
            }
        }
        dfs2(color[n]);
        get_ans(color[1],cmin[color[1]]);
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    ACM-ICPC 2018 徐州赛区网络预赛 D 杜教筛 前缀和
    51 Nod 1244 莫比乌斯函数前n项和
    20170914-构建之法:现代软件工程-阅读笔记
    结对-五子棋游戏-开发环境搭建过程
    结对-五子棋游戏-设计文档
    Git使用方法2.0
    团队-象棋游戏-团队信息
    Web开发技术——JQuery4(隐藏和显示、淡入和淡出、滑动)
    Web开发技术——JQuery3(事件)
    Web开发技术——JQuery2(语法和选择器)
  • 原文地址:https://www.cnblogs.com/Neptune0/p/11853500.html
Copyright © 2020-2023  润新知