• P1073 最优贸易


    哈哈哈

    终于过了

    这个题

    tarjan + topsort +一点小dp

    缩完点后再DAG上跑dp特别水的

    然而我确实傻乎乎的写爆炸里

    还是码力不够的事呀

    的确

    在DAG上跑DP

    是需要判断各个点和起点之间的关系的

    而且输出方案时

    也需要特别注意

    #include<iostream> 
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int price[100010];
    struct node
    {
        int point;
        int nxt;
    };
    node l1[1000010],l2[1000010];
    int h1[100010],h2[100010];
    int t1,t2;
    int tie;
    int dfn[100010],low[100010];
    bool instack[100010];
    int top,stack[100010];
    int belong[100010];
    int bcnt;
    int maxn[100010],minn[100010];
    int ans[100010];
    int in[100010];
    bool could[100010];
    int s[100010],t;
    void add1(int x,int y)
    {
        l1[++t1].point=y;
        l1[t1].nxt=h1[x];
        h1[x]=t1;
    }
    void add2(int x,int y)
    {
        l2[++t2].point=y;
        l2[t2].nxt=h2[x];
        h2[x]=t2;
    }
    void tarjan(int x)
    {
        stack[++top]=x;
        instack[x]=true;
        low[x]=dfn[x]=++tie;
        for(int i=h1[x];i;i=l1[i].nxt)
        {
             int net=l1[i].point;
             if(!dfn[net])
             {
             	tarjan(net);
             	if(low[net]<low[x])
             		low[x]=low[net];
             }
             else
             if(instack[net]&&dfn[net]<low[x])
             	low[x]=dfn[net];
        }
        if(dfn[x]==low[x])
        {
            bcnt+=1;
            int pass;
            do
            {
                pass=stack[top];
                top-=1;
                belong[pass]=bcnt;
                maxn[bcnt]=max(maxn[bcnt],price[pass]);
                minn[bcnt]=min(minn[bcnt],price[pass]);
                instack[pass]=false;
            }while(pass!=x);
        }
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            minn[i]=0x7fffffff;
        for(int i=1;i<=n;i++)
            scanf("%d",&price[i]);
        int a,b,c;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            add1(a,b);
            if(c==2)
                add1(b,a);
        }
        for(int i=1;i<=n;i++)
        if(!belong[i])
            tarjan(i);
        for(int i=1;i<=n;i++)
        {
            for(int j=h1[i];j;j=l1[j].nxt)
                if(belong[i]!=belong[l1[j].point])
                    {
                        in[belong[l1[j].point]]+=1;
                        add2(belong[i],belong[l1[j].point]);
                    }
        }
        if(in[belong[1]])
        {
            printf("0");
            return 0;
        }
        for(int i=1;i<=bcnt;i++)
            if(!in[i])
                s[++t]=i;
        could[belong[1]]=true;
        int pass;
        while(t)
        {
            pass=s[t];
            t-=1;
            if(could[pass])
                ans[pass]=max(ans[pass],maxn[pass]-minn[pass]);
            for(int i=h2[pass];i;i=l2[i].nxt)
            {
                int net=l2[i].point;
                could[net]=max(could[net],could[pass]);
                if(could[net])
                {
                	minn[net]=min(minn[net],minn[pass]);
                	ans[net]=max(ans[pass],ans[net]);
                }
                in[net]-=1;
                if(!in[net])
                    s[++t]=net;
            }
        }
        printf("%d",ans[belong[n]]);
    }
    
  • 相关阅读:
    SpringBoot配置文件数据格式三种写法
    实施工程师
    Linux命令大全
    PDCA原则
    cmd命令下载maven管理需要的依赖jar包
    java集合体系结构总结
    回溯
    红黑树详解
    Java 垃圾回收算法
    MySQL优化:如何避免回表查询?什么是索引覆盖
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/8633573.html
Copyright © 2020-2023  润新知