[luogu2607 ZJOI2008] 骑士 (树形dp)

题目描述

Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。

最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。

骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。

战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。

为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。

输入输出格式

输入格式:
输入文件knight.in第一行包含一个正整数N,描述骑士团的人数。

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

输出格式:
输出文件knight.out应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。

输入输出样例

输入样例#1:
3
10 2
20 3
30 1
输出样例#1:
30

说明

对于30%的测试数据,满足N ≤ 10;

对于60%的测试数据,满足N ≤ 100;

对于80%的测试数据,满足N ≤ 10 000。

对于100%的测试数据,满足N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。

做法

“我厌恶的人的厌恶的人不是我厌恶的人”
所以这个题与舞会很像不过会有环(无自环)
对于环如何处理呢?
我们在环上随意选取两个点 由题意可知他们是不能同时出现的 并且题中权值为点权
那我们只需放弃这条边然后各自跑一个舞会即可

code:

//By Menteur_Hxy
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <cmath>
#include <vector>
#include <queue>
#define M(a,b) memset(a,(b),sizeof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define LL long long
using namespace std;

inline LL rd() {
    LL x=0,fla=1; char c=' ';
    while(c>'9'|| c<'0') {if(c=='-') fla=-fla; c=getchar();}
    while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
    return x*fla;
}

inline void out(LL x){
    int a[25],wei=0;
    if(x<0) putchar('-'),x=-x;
    for(;x;x/=10) a[++wei]=x%10;
    if(wei==0){ puts("0"); return;}
    for(int j=wei;j>=1;--j) putchar('0'+a[j]);
    putchar('
');
}

const int N=1000010;
const int INF=0x3f3f3f3f;
int n,m,cnt;
int head[N],fa[N],v[N],ra[N],rb[N];
int to[N<<1],nex[N<<1];
LL f[N],g[N];

struct edges{
    int nex,to,dis;
}e[N];

int get(int x) {
	return fa[x]==x?x:fa[x]=get(fa[x]);
}

void add(int a,int b) {
	nex[++cnt]=head[a];
	to[cnt]=b;
	head[a]=cnt;
}

void dfs(int x,int pre) {
	f[x]=v[x],g[x]=0;
	for(int i=head[x];i;i=nex[i]) {
		if(to[i]==pre) continue;
		dfs(to[i],x);
		g[x]+=max(f[to[i]],g[to[i]]);
		f[x]+=g[to[i]];
	}
}

int main() {
    n=rd();
	F(i,1,n) fa[i]=i;
	F(i,1,n) {
		v[i]=rd(); int b=rd();
		if(get(i)!=get(b)) {
			add(i,b),add(b,i);
			fa[fa[i]]=fa[b];
		}
		else ra[++m]=i,rb[m]=b;
	}
	LL ans=0;
	F(i,1,m) { LL tp;
		dfs(ra[i],0),tp=g[ra[i]];
		dfs(rb[i],0),tp=max(tp,g[rb[i]]);
		ans+=tp;
	}
	out(ans);
	return 0;
}  
版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9148022.html