• luogu_P3387 【模板】缩点


    https://www.luogu.org/problem/P3387

    题目背景

    缩点+DP

    题目描述

    给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。

    允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。

    输入格式

    第一行,n,m

    第二行,n个整数,依次代表点权

    第三至m+2行,每行两个整数u,v,表示u->v有一条有向边

    输出格式

    共一行,最大的点权之和。

    输入输出样例

    输入 #1
    2 2
    1 1
    1 2
    2 1
    输出 #1
    2

    说明/提示

    n<=10^4,m<=10^5,0<=点权<=1000

    算法:Tarjan缩点+DAGdp


    缩点后拓扑更新

    #include<iostream>
    #include<cstdio>
    
    #define ri register int
    #define u int
    
    namespace opt {
    
        inline u in() {
            u x(0),f(1);
            char s(getchar());
            while(s<'0'||s>'9') {
                if(s=='-') f=-1;
                s=getchar();
            }
            while(s>='0'&&s<='9') {
                x=(x<<1)+(x<<3)+s-'0';
                s=getchar();
            }
            return x*f;
        }
    
    }
    
    using opt::in;
    
    #define NN 10005
    #define MM 100005
    
    #include<algorithm>
    
    namespace aft {
    
        u h[NN],va[NN],id[NN],cnt(1);
    
        struct node {
            u to,next;
        } a[MM];
    
        inline void add(const u &x,const u &y) {
            a[++cnt].to=y,a[cnt].next=h[x],h[x]=cnt;
        }
    
    }
    
    namespace mainstay {
    
        u h[NN],cnt(1);
    
        struct node {
            u to,next;
        } a[MM];
    
        inline void add(const u &x,const u &y) {
            a[++cnt].to=y,a[cnt].next=h[x],h[x]=cnt;
        }
    
        u stk[NN],va[NN],r,n,team[NN],num,low[NN],dfn[NN];
    
        void tarjan(const u &x) {
            low[x]=dfn[x]=++num,stk[++r]=x;
            for(ri i(h[x]); i; i=a[i].next) {
                u _y(a[i].to);
                if(!dfn[_y]) {
                    tarjan(_y);
                    low[x]=std::min(low[x],low[_y]);
                } else if(!team[_y]) low[x]=std::min(low[x],dfn[_y]);
            }
            if(dfn[x]==low[x]) {
                ++n;
                do {
                    team[stk[r]]=n;
                    aft::va[n]+=va[stk[r--]];
                } while(stk[r+1]^x);
            }
        }
    
        using aft::id;
    
        u q[NN],ans[NN];
    
        inline void solve() {
            u N(in()),M(in());
            for(ri i(1); i<=N; ++i) va[i]=in();
            for(ri j(1); j<=M; ++j) {
                u _a(in()),_b(in());
                add(_a,_b);
            }
            for(ri i(1); i<=N; ++i) {
                if(!dfn[i]) tarjan(i);
            }
            for(ri _x(1); _x<=N; ++_x) {
                for(ri i(h[_x]); i; i=a[i].next) {
                    u _y(a[i].to);
                    if(team[_x]^team[_y]) {
                        aft::add(team[_x],team[_y]),++id[team[_y]];
                    }
                }
            }
            u _r(0),_l(0);
            for(ri i(1); i<=n; ++i) if(!id[i]) q[++_r]=i,ans[i]=aft::va[i];
            while(_l+1<=_r) {
                u _x(q[++_l]);
                for(ri i(aft::h[_x]); i; i=aft::a[i].next) {
                    u _y(aft::a[i].to);
                    ans[_y]=std::max(ans[_y],ans[_x]+aft::va[_y]);
                    if(!--id[_y]) {
                        q[++_r]=_y;
                    }
                }
            }
            for(ri i(1);i<=n;++i) ans[0]=std::max(ans[0],ans[i]); 
            printf("%d",ans[0]);
        }
    
    }
    
    int main() {
    
        //freopen("x.txt","r",stdin);
        std::ios::sync_with_stdio(false);
        mainstay::solve();
    
    }
  • 相关阅读:
    问题:sqlserver 跨服务器连接;结果:Sql Server 跨服务器连接
    SpringBoot之Servlet、Filter、Listener配置
    spring boot 使用@ConfigurationProperties
    Mysql字段属性应该尽量设置为not null
    微服务—ELK分布式日志框架
    微服务—分布式服务追踪sleuth和zipkin
    微服务—熔断器Hystrix
    @RequestBody和@ResponseBody的使用情形以及RestTemplate的http报文转换
    application/x-www-form-urlencoded和multipart/form-data
    基于JWT的token身份认证方案
  • 原文地址:https://www.cnblogs.com/ling-zhi/p/11772737.html
Copyright © 2020-2023  润新知