【ZJOI2008】骑士
来源:互联网 发布:多线程编程 java 编辑:程序博客网 时间:2024/04/29 23:13
【ZJOI2008】骑士
Description
Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。
最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。
骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。
战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。
为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。
最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。
骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。
战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。
为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。
Input
输入文件knight.in第一行包含一个正整数N,描述骑士团的人数。
接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。
接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。
Output
输出文件knight.out应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。
Sample Input
3
10 2
20 3
30 1
10 2
20 3
30 1
Sample Output
30
Hint
【数据规模】
对于30%的测试数据,满足N ≤ 10;
对于60%的测试数据,满足N ≤ 100;
对于80%的测试数据,满足N ≤ 10 000。
对于100%的测试数据,满足N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。
对于30%的测试数据,满足N ≤ 10;
对于60%的测试数据,满足N ≤ 100;
对于80%的测试数据,满足N ≤ 10 000。
对于100%的测试数据,满足N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。
Solution
我们来读读题~n个点,n条边,这像是什么东西呢???
如果联通的话,当然是我们可爱的环套树了。
那么题目就是一片只有一颗环套树的森林了,所有节点不能与它相连的节点一起选中,所以这道题可以简单的抽象为:环套树的最大独立集。
我们将环上的一条边断掉,然后以两个断点分别为根做一次树形dp。注意:两个断点不能同时选择。
至于判断环的过程可以简单地用一个dfs,如果一个遍历到的节点不是当前节点的父节点,但是却已经被标记访问的话,那么这两个点就肯定在环上。
dp方程:f[i][0]=sum(max(f[son][0],f[son][1])),f[i][1]=sum(f[son][0]),其中son为i节点的子节点。
如果联通的话,当然是我们可爱的环套树了。
那么题目就是一片只有一颗环套树的森林了,所有节点不能与它相连的节点一起选中,所以这道题可以简单的抽象为:环套树的最大独立集。
我们将环上的一条边断掉,然后以两个断点分别为根做一次树形dp。注意:两个断点不能同时选择。
至于判断环的过程可以简单地用一个dfs,如果一个遍历到的节点不是当前节点的父节点,但是却已经被标记访问的话,那么这两个点就肯定在环上。
dp方程:f[i][0]=sum(max(f[son][0],f[son][1])),f[i][1]=sum(f[son][0]),其中son为i节点的子节点。
CODE
#include<iostream>#include<cstring>#include<cstdio>using namespace std;inline int read(){char c;int rec=0;while((c=getchar())<'0'||c>'9');while(c>='0'&&c<='9')rec=rec*10+c-'0',c=getchar();return rec;}int n;long long a[1000005];bool vis[1000005];struct Branch {int next,to;}branch[2000005];int h[1000005],cnt=1;inline void add(int x,int y) {branch[++cnt].to=y;branch[cnt].next=h[x];h[x]=cnt;return ;}int P,Q,lim;long long ans=0;bool flag[1000005],F;inline void Dfs_Ring(int v,int pre){flag[v]=1;vis[v]=1;for(int i=h[v];i;i=branch[i].next){int j=branch[i].to;if(j==pre)continue;if(flag[j]==1){lim=i;P=j;Q=v;continue;}Dfs_Ring(j,v);}}long long dp[1000005][2];inline void Dfs_Val(int v,int pre){dp[v][1]=a[v];dp[v][0]=0;for(int i=h[v];i;i=branch[i].next){if(i==lim||i==(lim^1))continue;int j=branch[i].to;if(j==pre)continue;Dfs_Val(j,v);dp[v][1]+=dp[j][0];dp[v][0]+=max(dp[j][0],dp[j][1]);}if(v==Q)dp[v][1]=0;return ;}inline void Sov(int v){F=0;lim=0;P=v;Dfs_Ring(v,0);Dfs_Val(P,0);long long temp=max(dp[P][0],dp[P][1]);Q=0;Dfs_Val(P,0);temp=max(temp,dp[P][0]);ans+=temp;return ;}int main(){n=read();for(int i=1;i<=n;i++){a[i]=read();int x=read();add(i,x);add(x,i);}for(int i=1;i<=n;i++){if(!vis[i])Sov(i);}cout<<ans;return 0;}代码偏丑,无向图断边时注意将反方向的边也标记上
阅读全文
0 0
- [ZJOI2008]骑士
- [ZJOI2008]骑士
- [ZJOI2008]骑士
- 【ZJOI2008】骑士
- 【ZJOI2008】骑士
- [ZJOI2008]Knight骑士
- BZOJ 1040: [ZJOI2008]骑士
- BZOJ1040 [ZJOI2008]骑士
- bzoj 1040: [ZJOI2008]骑士
- 【BZOJ 1040】 [ZJOI2008]骑士
- [ZJOI2008]骑士解题报告
- 【bzoj1040】【ZJOI2008】【骑士】
- bzoj1040: [ZJOI2008]骑士 dp
- 1040: [ZJOI2008]骑士
- [BZOJ1040][ZJOI2008]骑士
- 1040: [ZJOI2008]骑士
- 【算法题】[ZJOI2008]骑士
- BZOJ 1040: [ZJOI2008]骑士
- 练习 2017-08-15 文件的随机访问
- 拓展欧几里得 [Noi2002]Savage
- 集训第十六天(2017/8/15):树状数组
- LYOS —— Driver for Keyboard & Mouse
- 几种常用的传感器(加速度传感器、重力传感器、方向传感器、陀螺仪)简介
- 【ZJOI2008】骑士
- poj 2559 单调栈
- Ubuntu 安装Phpstorm+汉化+激活
- 回环变位(Circular Rotation)
- 定位与层级
- mybatis 查询
- 构建Sql多条件查询语句
- 『洛谷T7835』士兵站队问题
- 【JZOJ 5272】神奇的重复序列