• Bzoj2427: [HAOI2010]软件安装


    思路:Tarjan找环,缩点。然后再进行树上背包问题

    注意两套图不要用混了

    /**************************************************************
        Problem: 2427
        User: Bj2002
        Language: C++
        Result: Accepted
        Time:212 ms
        Memory:1500 kb
    ****************************************************************/
     
    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <algorithm>
    #include <fstream>
    #define re register
    #define GC getchar()
    #define Clean(X,K) memset(X,K,sizeof(X))
    #define Min(X,Y) ((X)<(Y)?(X):(Y))
    #define Max(X,Y) ((X)>(Y)?(X):(Y))
    #include <iostream>
    using namespace std ;
    int Qread () {
        int X = 0 ;
        char C = GC ;
        while (C > '9' || C < '0') C = GC ;
        while (C >='0' && C <='9') {
            X = X * 10 + C - '0' ;
            C = GC ;
        }
        return X ;
    }
    const int Maxn = 105 , Maxm = 505 , INF = 20021020 << 2;
    int Ind[Maxn] , F[Maxn][Maxm] , En = 0 , Head[Maxn] , C = 0 , Cor[Maxn] , Vis[Maxn] , St[Maxn] , Top = 0 , N , M , w[Maxn] ,W[Maxn] ,  v[Maxn] , V[Maxn] , D[Maxn] , Cnt = 0 , Low[Maxn] , Dfn[Maxn];
    struct Edge {
        int From_Point , Goto_Point , Next_Edge ;
    };
    Edge E[Maxn] ;
    void Tarjan (int X) {
        Low[X] = Dfn[X] = ++ Cnt ;
        Vis[X] = 1 ;
        St[++ Top] = X ;
        if (D[X]) {
            if (!Dfn[D[X]]) {
                Tarjan (D[X]) ;
                Low[X] = Min (Low[X] , Low[D[X]]) ;
            } else if (Vis[D[X]]) Low[X] = Min (Low[X] , Dfn[D[X]]) ;
        }
        if (Low[X] == Dfn[X]) {
            ++ C ;
            while (St[Top] != X) {
                V[C] += v[St[Top]] ;
                W[C] += w[St[Top]] ;
                Vis[St[Top]] = 0 ;
                Cor[St[Top]] = C ;
                -- Top ;
            }
            V[C] += v[X] ;
            W[C] += w[X] ;
            Cor[X] = C ;
            Vis[X] = 0 ;
            -- Top ;
        }
    }
    void Adg (int X , int Y) {
        E[++En].From_Point = X ;
        E[En].Goto_Point = Y ;
        E[En].Next_Edge = Head[X] ;
        Head[X] = En ;
    }
    void DFS (int X) {
        for (re int i = Head[X] ; i ; i = E[i].Next_Edge ) {
            DFS (E[i].Goto_Point ) ; 
            for (re int j = M ; j >= 0 ; -- j) for (re int k = 0 ; k <=j ; ++ k) F[X][j] = Max (F[X][j] , F[X][j - k] + F[E[i].Goto_Point ][k]) ;
        }
        for (re int i = M ; i >= W[X] ; -- i) F[X][i] = F[X][i - W[X]] + V[X] ;
        for (re int i = W[X] - 1; i >= 0 ; -- i) F[X][i] = 0 ;
    }
    int main () {
    //  freopen ("P2515.in" , "r" , stdin) ;
    //  freopen ("my.out" , "w" , stdout) ;
        N = Qread () , M = Qread () ;
        for (re int i = 1 ; i <= N; ++ i) w[i] = Qread () ;
        for (re int i = 1 ; i <= N; ++ i) v[i] = Qread () ;
        for (re int i = 1 ; i <= N; ++ i) D[i] = Qread () ;
        for (re int i = 1 ; i <= N; ++ i) if (!Dfn[i]) Tarjan(i) ;
        Clean(Head , 0) , Clean (F , 0) ;
        for (re int i = 1 ; i <= N; ++ i) if (Cor[i] != Cor[D[i]] && D[i]) {
                if (!F[Cor[D[i]]][Cor[i]]) {
                    Adg (Cor[D[i]] , Cor[i]) ;
                    ++ Ind[Cor[i]] ;
                    F[Cor[D[i]]][Cor[i]] = INF ;
                }
            }
        V[0] = 0 , W[0] = 0 ;
        for (re int i = 1 ; i <= C; ++ i) if (!Ind[i]) Adg (0 , i) ;
        Clean(F , 0) ;
        DFS (0) ;
        cout << F[0][M]<<endl;
        fclose (stdin) , fclose (stdout) ;
        return 0 ;
    }
  • 相关阅读:
    如何用css画一个文件上传图案?
    Vue.js命名风格指南
    JS的静态类型检测,有内味儿了
    每天认识几个HTTP 响应码
    剑指offer二叉树算法题JavaScript整理
    javascript
    JS数据结构与算法
    (转自MDN)CSS基础一定要看的包含块(containing block)
    简单记记display中inline、block、inline-block以及常见行内/块内元素
    从计算机操作系统中了解并发与并行、进程与线程
  • 原文地址:https://www.cnblogs.com/bj2002/p/10650871.html
Copyright © 2020-2023  润新知