第一次做环套树的题

这道题题目中貌似是有向边,实际上想一想就知道是无向的。

因为一个骑士觉得另一个骑士丑他们俩就走不到一起。

所以整个图实际上是一个无向环套树森林。

对于每一棵环套树,先dfs找环,找到环以后断环为链并将断开的两个点强制其中一个点为根且不选做一次树形DP,对另一个点做同样操作。

取两次结果最大值加入ans

  1 /*
  2 ID:WULALA
  3 PROB:bzoj1040
  4 LANG:C++
  5 */
  6 #include <cstdio>
  7 #include <cstring>
  8 #include <algorithm>
  9 #include <cmath>
 10 #include <iostream>
 11 #include <fstream>
 12 #include <ctime>
 13 #define N 1000008
 14 #define M
 15 #define mod
 16 #define mid(l,r) ((l+r) >> 1)
 17 #define INF 0x7ffffff
 18 using namespace std;
 19
 20 int dfn[N],que,n,g[N],f[N],u,v,w[N],r,tot,ans,head[N],fa[N];
 21 bool vis[N];
 22
 23 struct WULALA
 24 {
 25     int node,next;
 26 }e[2*N];
 27
 28 void add(int x,int y)
 29 {
 30     e[++tot].node = y;
 31     e[tot].next = head[x];
 32     head[x] = tot;
 33     e[++tot].node = x;
 34     e[tot].next = head[y];
 35     head[y] = tot;
 36 }
 37
 38 void init()
 39 {
 40     scanf("%d",&n);
 41     for (int i = 1;i <= n;i++)
 42     {
 43         int b;
 44         scanf("%d%d",&w[i],&b);
 45         add(i,b);
 46     }
 47 }
 48
 49 void find_cir(int a)
 50 {
 51     vis[a] = true;
 52     int c = head[a];
 53     while(c)
 54     {
 55         if (e[c].node == fa[a])
 56             {c = e[c].next; continue;}
 57         if (vis[e[c].node])
 58         {
 59             u = e[c].node;
 60             v = a;
 61         }
 62         else
 63         {
 64             fa[e[c].node] = a;
 65             find_cir(e[c].node);
 66         }
 67         c = e[c].next;
 68     }
 69 }
 70
 71 int dfs(int a,int m)
 72 {
 73     if (m != v) f[a] = w[a];
 74     int c = head[a];
 75     while(c)
 76     {
 77         if (e[c].node == fa[a]||e[c].node == u)
 78         {c = e[c].next; continue;}
 79         fa[e[c].node] = a;
 80         dfs(e[c].node,m);
 81         g[a] += max(g[e[c].node],f[e[c].node]);
 82         f[a] += g[e[c].node];
 83         c = e[c].next;
 84     }
 85     if (a == u)
 86     {
 87         if (m == u) return g[u];
 88         return (max(g[u],f[u]));
 89     }
 90 }
 91
 92 void work(int a)
 93 {
 94     int r;
 95     memset(f,0,sizeof(f));
 96     memset(g,0,sizeof(g));
 97     memset(fa,0,sizeof(fa));
 98     find_cir(a);
 99     memset(fa,0,sizeof(fa));
100     memset(f,0,sizeof(f));
101     memset(g,0,sizeof(g));
102     fa[u] = v;
103     r = dfs(u,v);
104     memset(f,0,sizeof(f));
105     memset(g,0,sizeof(g));
106     r = max(r,dfs(u,u));
107     ans += r;
108 }
109
110 int main()
111 {
112     init();
113     for (int i = 1;i <= n;i++)
114         if (!vis[i]) work(i);
115     printf("%d\n",ans);
116     return 0;
117 }

View Code

转载于:https://www.cnblogs.com/wulala979/p/3507755.html

bzoj 1040: [ZJOI2008]骑士相关推荐

  1. bzoj 1040: [ZJOI2008]骑士 树形dp

    题目链接 1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3054  Solved: 1162 [Submit] ...

  2. 基环树DP(bzoj 1040: [ZJOI2008]骑士)

    树:n个点n-1条边的连通图 基环树:n个点n条边的连通图,也就是一个环套着多棵树 基环树DP:找到环上任意相邻两点,断掉这两点之间的边,就形成了一棵树 之后对这两点分别进行一次树形DP即可 例题: ...

  3. BZOJ 1040 ZJOI2008 骑士 树形DP

    题目大意:给定一个基环树林,每一个点上有权值,要求选择一个权值和最大的点集,要求点集中的随意两个点之间不能直接相连 最大点独立集--考虑到n<=100W,网络流铁定跑不了,于是我们考虑树形DP ...

  4. BZOJ 1040 [ZJOI2008]骑士

    内向树dp~ 就是先找环,任取环上有边相连两点,u和v,以u为根,断开u和v之间的边,做两次树形dp,dp[i][0]表示i不选,dp[i][1]表示i选 ①强制u不选,v随意 ②u随意,v不选 两种 ...

  5. bzoj 1040 1040: [ZJOI2008]骑士

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 5210  Solved: 1987 [Submit][Stat ...

  6. 1040: [ZJOI2008]骑士

    Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7113  Solved: 2797 [Submit][Status][Discuss] Descri ...

  7. BZOJ1040: [ZJOI2008]骑士

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 5332  Solved: 2023 [Submit][Stat ...

  8. P2607 [ZJOI2008]骑士

    P2607 [ZJOI2008]骑士 题意: n个点n个边,每个点都有权值,相邻的点不能同时选择,问如何选择能使得权值最大 题解: 这个题很有P1352 没有上司的舞会这个题的感觉,唯一的区别是那个题 ...

  9. bzoj 1038 [ZJOI2008]瞭望塔

    1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2438  Solved: 1004 [Submit][Sta ...

最新文章

  1. 线段树segment_tree go语言实现
  2. Python 学习笔记12 类 - 使用类和实例
  3. Error: listen EACCES 127.0.0.1
  4. ASP.NET Core Web API 集成测试中使用 Bearer Token
  5. python脚本根据cookies自动登录网站_python实现带验证码网站的自动登陆实现代码...
  6. 添加lua_C++/Lua高级交互
  7. 【BZOJ3997】组合数学,总之是DP就对了
  8. html链接sqlserver,js连接sqlserver进行查询
  9. systemd.generator — systemd unit generators
  10. python写excel
  11. 蓝桥杯 ADV-178 算法提高 简单加法
  12. 【To Do! 重点 正则表达式】LeetCode 65. Valid Number
  13. 两台笔记本用wifi建立局域网_无线通信技术——WiFi
  14. NTKO控件安装:“不能装载文档控件,请在检查浏览器的选项中检查浏览器的安全设置”问题
  15. OpenCV教程:超详细的OpenCV入门教程,值得收藏
  16. 和数传媒:区块链博弈论机制设计是未来关键
  17. CSS的行内样式与内联样式,看完就会了
  18. 熊猫猪新系统测试之三:iOS 8.0.2
  19. Pyinstaller的Spec文件用法
  20. 【深入PHP 面向对象】读书笔记(四) - 对象与设计

热门文章

  1. 指针法算中点坐标c语言,C语言:利用指针编写程序,用梯形法计算给定的定积分实例...
  2. think php union,UNION -ThinkPHP3.2.3完全开发手册 | AnSpoon.Com
  3. C++STL查找,lower_bound()函数和upper_bound()函数的区别
  4. HTML表格修改字段,HTML表格 – 更改列中单个单元格的宽度
  5. 应用系统运行监控界面_重庆悦来会展二期电力监控系统的设计与应用
  6. asp 检测更改后缀的图片_微信不能发送25M以上视频?一键修改后缀名,就能立马发送...
  7. 图像过滤,so easy~~
  8. php7会不会出问题,升级到PHP7后会话不工作
  9. python list二维数组_python中的二维数组和lamda
  10. 二分查找 递归与非递归实现