zoukankan      html  css  js  c++  java
  • BZOJ1040 [ZJOI2008]骑士

    首先,建出来的是无向图,因为a看不上b他们一定不会一起被选出。。。

    然后,n个点n条边,形成的是环套树森林

    于是有个奇技淫巧的做法,先dfs一遍找到环上的两个点,然后拆掉那条边,记下来边的两端x, y两个节点

    强制x为根且x不选做树形动规,然后强制y为根且y不选再做一遍树形动规,两次的最大值加入答案

    注意写法,我记录了father就找不到二元环的情况了QAQQQ,WA到死。。。要记录来的那条边

     1 /**************************************************************
     2     Problem: 1040
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:1992 ms
     7     Memory:51724 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12  
    13 using namespace std;
    14 const int N = 1e6 + 5;
    15  
    16 struct edge {
    17     int next, to, f;
    18     edge() {}
    19     edge(int _n, int _t, int _f = 1) : next(_n), to(_t), f(_f) {}
    20 } e[N << 1];
    21  
    22 int n, rt1, rt2;
    23 int first[N], tot = 1;
    24 int v[N], vis[N];
    25 long long f[N][2], ans;
    26  
    27 inline int read() {
    28     int x = 0;
    29     char ch = getchar();
    30     while (ch < '0' || '9' < ch)
    31         ch = getchar();
    32     while ('0' <= ch && ch <= '9') {
    33         x = x * 10 + ch - '0';
    34         ch = getchar();
    35     }
    36     return x;
    37 }
    38  
    39 inline void Add_Edges(int x, int y) {
    40     e[++tot] = edge(first[x], y), first[x] = tot;
    41     e[++tot] = edge(first[y], x), first[y] = tot;
    42 }
    43  
    44 #define y e[x].to
    45 void dfs(int p, int from) {
    46     int x;
    47     vis[p] = 1;
    48     for (x = first[p]; x; x = e[x].next) 
    49         if (!vis[y]) dfs(y, x);
    50         else if ((from ^ 1) != x && !rt1)
    51             rt1 = p, rt2 = y, e[x].f = e[x ^ 1].f = 0;
    52 }
    53  
    54 void dp(int p, int t) {
    55     int x;
    56     vis[p] = t;
    57     f[p][0] = 0, f[p][1] = v[p];
    58     for (x = first[p]; x; x = e[x].next)
    59         if (vis[y] != t && e[x].f) {
    60             dp(y, t);
    61             f[p][0] += max(f[y][0], f[y][1]);
    62             f[p][1] += f[y][0];
    63         }
    64 }
    65 #undef y
    66  
    67 int main() {
    68     int i;
    69     long long tmp;
    70     n = read();
    71     for (i = 1; i <= n; ++i)
    72         v[i] = read(), Add_Edges(read(), i);
    73     for (i = 1; i <= n; ++i)
    74         if (!vis[i]) {
    75             rt1 = rt2 = 0;
    76             dfs(i, 0);
    77             dp(rt1, 2), tmp = f[rt1][0];
    78             dp(rt2, 3), ans += max(tmp, f[rt2][0]);
    79         }
    80     printf("%lld
    ", ans);
    81     return 0;
    82 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    GIT配置及用法
    Web前端深思
    SPA解释:单页应用程序
    对 Sea.js 进行配置(一) seajs.config
    前端开发知识体系技能点【根据自我学习顺序】
    App性能提升方法
    浅谈Bootstrap自适应功能在Web开发中的应用
    《写给大家看的设计书》 读书笔记(三)
    《写给大家看的设计书》读书笔记(一)
    《写给大家看的设计书》读书笔记(二)
  • 原文地址:https://www.cnblogs.com/rausen/p/4345378.html
Copyright © 2011-2022 走看看