zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      题目传送门

    Running In The Sky

    格式难调,题面就不放了。


      分析:

      一句话题意:给定一张带点权的有向图,求最长点权路径及该路径上的最大点权。

      很明显的$DAGDP$,因此需要缩点,将该图重建为一张$DAG$,在每个强联通分量中记录两个变量$sum,mx$表示该强联通分量中的点权和及最大点权。然后就是$DP$了,因为不仅要求最长点权路径,还要求路径上的最大点权,所以我们可以记录状态$f[x][0]$和$f[x][1]$分别表示以$x$为终点的路径中点权和最大的路径以及该路径上的最大点权。共有两个方程:

    $egin{cases}f[y][0]=f[x][0],f[y][1]=f[x][1] & (f[x][0]>f[y][0])\f[y][1]=max(f[y][1],f[x][1]) & (f[x][0]==f[y][0]) end{cases}$

      这样子这题就很好解决了。

      Code:

    //It is made by HolseLee on 26th Oct 2018
    //Luogu.org P4742
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=2e5+7, M=5e5+7;
    int n,m,val[N],ans0,ans1,h[N],head[N],cnte,dg[N],f[N][2];
    int scc[N],mx[N],sum[N],idx,dfn[N],low[N],tot;
    bool ins[N];
    struct Edge { int to,nxt; }edge[M],e[M];
    queue<int>q; stack<int>t;
    
    inline int read()
    {
        char ch=getchar(); int x=0; bool flag=false;
        while( ch<'0' || ch>'9' ) {
            if( ch=='-' ) flag=true; ch=getchar(); }
        while( ch>='0' && ch<='9' ) {
            x=x*10+ch-'0'; ch=getchar(); }
        return flag ? -x : x;
    }
    
    inline void add_edge(int x,int y)
    {
        edge[++cnte].to=y;
        edge[cnte].nxt=h[x];
        h[x]=cnte;
    }
    
    inline void add(int x,int y)
    {
        e[++cnte].to=y, e[cnte].nxt=head[x];
        head[x]=cnte, dg[y]++;
    }
    
    void tarjan(int x)
    {
        dfn[x]=low[x]=++idx; ins[x]=1; t.push(x);
        int y;
        for(int i=h[x]; i; i=edge[i].nxt) {
            y=edge[i].to;
            if( !dfn[y] ) {
                tarjan(y);
                low[x]=min(low[x],low[y]);
            } else if( ins[y] ) {
                low[x]=min(low[x],dfn[y]);
            }
        }
        if( dfn[x]==low[x] ) {
            ++tot;
            do {
                y=t.top(); t.pop(); ins[y]=false; scc[y]=tot;
                sum[tot]+=val[y], mx[tot]=max(mx[tot],val[y]);
            } while( y!=x );
        }
    }
    
    void rebuild()
    {
        cnte=0;
        for(int x=1; x<=n; ++x)
        for(int i=h[x],y; i; i=edge[i].nxt) {
            y=edge[i].to;
            if( scc[x]!=scc[y] ) add(scc[x],scc[y]);
        }
    }
    
    int main()
    {
        n=read(), m=read();
        for(int i=1; i<=n; ++i) val[i]=read();
        for(int i=1; i<=m; ++i) add_edge(read(), read());
        for(int i=1; i<=n; ++i) if( !dfn[i] ) tarjan(i);
        rebuild();
        for(int i=1; i<=tot; ++i) if( !dg[i] ) q.push(i);
        while( !q.empty() ) {
            int x=q.front(); q.pop();
            f[x][0]+=sum[x]; f[x][1]=max(f[x][1],mx[x]);
            for(int i=head[x],y; i; i=e[i].nxt) {
                y=e[i].to;
                if( !(--dg[y]) ) q.push(y);
                if( f[x][0]>f[y][0] ) {
                    f[y][0]=f[x][0], f[y][1]=f[x][1];
                } else if( f[y][0]==f[x][0] ) {
                    f[y][1]=max(f[y][1],f[x][1]);
                }
            }
        }
        for(int i=1; i<=tot; ++i)
        if( f[i][0]>ans0 ) {
            ans0=f[i][0], ans1=f[i][1];
        } else if( f[i][0]==ans0 ) {
            ans1=max(ans1,f[i][1]);
        }
        printf("%d %d
    ",ans0,ans1);
        return 0;
    }
  • 相关阅读:
    Angular
    Angular
    Angular
    Angular
    Angular
    Angular
    Angular
    springsecurity 源码解读 之 RememberMeAuthenticationFilter
    springsecurity 源码解读之 AnonymousAuthenticationFilter
    springsecurity 源码解读之 SecurityContext
  • 原文地址:https://www.cnblogs.com/cytus/p/9858426.html
Copyright © 2011-2022 走看看