1040: [ZJOI2008]骑士

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1190  Solved: 465
[Submit][Status]

Description

Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。

Input

第一行包含一个正整数N,描述骑士团的人数。接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。

Output

应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。

 
分析:
  由于每个人只有一个最讨厌的人,构造出的图形一个连通块里最多只有一个基环,假设为root...-ban-root。
  显然最优值从选取root或者不选取root中选出。
  考虑到如果是奇数环时,选取了root,就不能再选取ban。如果不选root的话,ban可选可不选。
  于是我们考虑两种情况:
  1.强制root不选,ban随意。
  2.强制ban不选,root随意。
  先dfs找到root以及ban,对于两种情况分别进行树上DP即可。
 
  1. #include <set>
  2. #include <map>
  3. #include <list>
  4. #include <cmath>
  5. #include <queue>
  6. #include <stack>
  7. #include <string>
  8. #include <vector>
  9. #include <cstdio>
  10. #include <cstring>
  11. #include <iostream>
  12. #include <algorithm>
  13.  
  14. using namespace std;
  15.  
  16. typedef long long ll;
  17. typedef unsigned long long ull;
  18.  
  19. #define debug puts("here")
  20. #define rep(i,n) for(int i=0;i<n;i++)
  21. #define rep1(i,n) for(int i=1;i<=n;i++)
  22. #define REP(i,a,b) for(int i=a;i<=b;i++)
  23. #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
  24. #define pb push_back
  25. #define RD(n) scanf("%d",&n)
  26. #define RD2(x,y) scanf("%d%d",&x,&y)
  27. #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
  28. #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
  29. #define All(vec) vec.begin(),vec.end()
  30. #define MP make_pair
  31. #define PII pair<int,int>
  32. #define PQ priority_queue
  33. #define cmax(x,y) x = max(x,y)
  34. #define cmin(x,y) x = min(x,y)
  35. #define Clear(x) memset(x,0,sizeof(x))
  36. /*
  37.  
  38. #pragma comment(linker, "/STACK:1024000000,1024000000")
  39.  
  40. int size = 256 << 20; // 256MB
  41. char *p = (char*)malloc(size) + size;
  42. __asm__("movl %0, %%esp\n" :: "r"(p) );
  43.  
  44. */
  45.  
  46. /******** program ********************/
  47.  
  48. const int MAXN = 1e6+5;
  49.  
  50. int po[MAXN],tol;
  51. ll dp[MAXN][2];
  52. int val[MAXN],n;
  53.  
  54. struct Edge{
  55. int y,next;
  56. }edge[MAXN<<1];
  57.  
  58. inline void add(int x,int y){
  59. edge[++tol].y = y;
  60. edge[tol].next = po[x];
  61. po[x] = tol;
  62. }
  63.  
  64. int root,ban;
  65. bool use[MAXN],vis[MAXN][2];
  66.  
  67. void dfsCir(int x,int fa){
  68. use[x] = true;
  69. for(int i=po[x];i;i=edge[i].next){
  70. int y = edge[i].y;
  71. if(y==fa)continue;
  72. if(!use[y])dfsCir(y,x);
  73. else root = x , ban = y;
  74. }
  75. }
  76.  
  77. void dfsAns(int x){
  78. dp[x][0] = 0;
  79. dp[x][1] = val[x];
  80. vis[x][0] = 1;
  81. for(int i=po[x];i;i=edge[i].next){
  82. int y = edge[i].y;
  83. if(vis[y][0])continue;
  84. dfsAns(y);
  85. dp[x][0] += max(dp[y][0],dp[y][1]);
  86. dp[x][1] += dp[y][0];
  87. }
  88. }
  89.  
  90. void dfsBan(int x){
  91. dp[x][0] = 0;
  92. dp[x][1] = val[x];
  93. vis[x][1] = 1;
  94. for(int i=po[x];i;i=edge[i].next){
  95. int y = edge[i].y;
  96. if(vis[y][1])continue;
  97. dfsBan(y);
  98. if(y==ban){
  99. dp[x][0] += dp[y][0];
  100. dp[x][1] += dp[y][0];
  101. }else{
  102. dp[x][0] += max(dp[y][0],dp[y][1]);
  103. dp[x][1] += dp[y][0];
  104. }
  105. }
  106. }
  107.  
  108. int main(){
  109.  
  110. #ifndef ONLINE_JUDGE
  111. freopen("sum.in","r",stdin);
  112. //freopen("sum.out","w",stdout);
  113. #endif
  114.  
  115. while(~RD(n)){
  116. Clear(po);
  117. tol = 0;
  118. int y;
  119. rep1(x,n){
  120. RD2(val[x],y);
  121. add(x,y);
  122. add(y,x);
  123. }
  124.  
  125. Clear(dp);
  126. Clear(use);
  127. Clear(vis);
  128.  
  129. ll ans = 0;
  130. rep1(i,n)
  131. if(!use[i]){
  132. ban = 0;
  133. root = i;
  134. dfsCir(i,0);
  135.  
  136. dfsAns(root);
  137. ll tmp = dp[root][0];
  138.  
  139. dfsBan(root);
  140. ans += max( tmp,max(dp[root][0],dp[root][1]) );
  141. }
  142. cout<<ans<<endl;
  143. }
  144.  
  145. return 0;
  146. }

  

 

BZOJ 1040: [ZJOI2008]骑士 基环加外向树的更多相关文章

  1. BZOJ 1040 [ZJOI2008]骑士 (基环树+树形DP)

    <题目链接> 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...

  2. bzoj 1040: [ZJOI2008]骑士 環套樹DP

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1755  Solved: 690[Submit][Status] ...

  3. [BZOJ 1040][ZJOI2008]骑士

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5403  Solved: 2060[Submit][Status ...

  4. Bzoj 1040 [ZJOI2008]骑士 题解

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5368  Solved: 2044[Submit][Status ...

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

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

  6. bzoj 1040 [ZJOI2008]骑士(基环外向树,树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题意] 给一个基环森林,每个点有一个权值,求一个点集使得点集中的点无边相连且权 ...

  7. [BZOJ 1040] [ZJOI2008] 骑士 【基环+外向树DP】

    题目链接:BZOJ - 1040 题目分析 这道题目的模型就是一个图,不一定联通,每个连通块的点数等于边数. 每个连通块都是一个基环+外向树.即树上增加了一条边. 如果是树,就可以直接树形DP了.然而 ...

  8. BZOJ 1040:[ZJOI2008]骑士(环套外向树+树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题目大意] 给出环套外向树森林,求最大权独立集. [题解] 我们对于每个连通块 ...

  9. BZOJ 1040: [ZJOI2008]骑士 [DP 环套树]

    传送门 题意:环套树的最大权独立集 一开始想处理出外向树树形$DP$然后找到环再做个环形$DP$ 然后看了看别人的题解其实只要断开环做两遍树形$DP$就行了...有道理! 注意不连通 然后洛谷时限再次 ...

随机推荐

  1. 可以binidng属性的属性【项目】

    1:binding后台bool[]数据以及后台ObservableCollection数据 分别见下面xaml的Visibility和Text的Binding public bool[] Rubber ...

  2. Spring AOP 实现原理

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  3. 25.怎样创建一个Swift项目?

    经历前面三部分的学习之后,我们对于Swift的有了基本的了解,知道它的基础语法,也知道了类.结构体.枚举.协议.扩展等等内容.但知道上面这些内容,并不代表我们就能很好的进行实际的项目开发了,本部分内容 ...

  4. MyEclipse卡死解决

    MyEclipse卡死解决 在用[MyEclipse] 写代码很容易卡死机,尤其是在对JSP文件的<%%>之间写代码的时候,只要一弹出智能提示就立刻卡死,程序失去响应,我以为是MyEcli ...

  5. mysql主从同步单个表实验记录

    问题的提出: 在CRM管理系统与运营基础数据平台之间需要有数据表进行交换,说是交换,其实是单向的,就是CRM里面的一些数据需要实时同步到运营基础数据平台中. 解决方案: A.采用时间戳的办法进行代码开 ...

  6. C++ CopyFile

    复制文件 关键点 CopyFile The CopyFile function copies an existing file to a new file. The CopyFileEx functi ...

  7. 【JavaScript】Object.observe()带来的数据绑定变革

    Object.observe()带来的数据绑定变革 引言 一场变革即将到来.一项Javascript中的新特性将会改变你对于数据绑定的所有认识.它也将改变你所使用的MVC库观察模型中发生的修改以及更新 ...

  8. python time模块详解(转)

    python 的内嵌time模板翻译及说明  一.简介   time模块提供各种操作时间的函数  说明:一般有两种表示时间的方式:       第一种是时间戳的方式(相对于1970.1.1 00:00 ...

  9. 【Python】 做一个简单的 http server

    # coding=utf-8 ''' Created on 2014年6月15日 @author: Yang ''' import socket import datetime # 初始化socket ...

  10. 疑难杂症:java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion(Ljava/lang/String;)V

    错误: java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion(Ljava/lang/Strin ...