[洛谷1271] 聚会的快乐


题目描述

你要组织一个由你公司的人参加的聚会。你希望聚会非常愉快,尽可能多地找些有趣的热闹。但是劝你不要同时邀请某个人和他的上司,因为这可能带来争吵。给定N个人(姓名,他幽默的系数,以及他上司的名字),编程找到能使幽默系数和最大的若干个人。


输入格式

第一行一个整数N(N<100)。接下来有N行,每一行描述一个人的信息,信息之间用空格隔开。姓名是长度不超过20的字符串,幽默系数是在0到100之间的整数。


输出格式

所邀请的人最大的幽默系数和。


样例数据

样例输入

5
BART 1 HOMER
HOMER 2 MONTGOMERY
MONTGOMERY 1 NOBODY
LISA 3 HOMER
SMITHERS 4 MONTGOMERY

样例输出

8


说明

洛谷第四组数据有错,其中有重名情况,WA的不用理他。


题目分析

类似[Ural 1039] 没有上司的晚会
用map处理人的名字,Trie树也可以


源代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline const long long Get_Int() {
    long long num=0,bj=1;
    char x=getchar();
    while(x<'0'||x>'9') {
        if(x=='-')bj=-1;
        x=getchar();
    }
    while(x>='0'&&x<='9') {
        num=num*10+x-'0';
        x=getchar();
    }
    return num*bj;
}
map<string,long long>M;
struct Edge {
    int to,next;
} Edge[50005];
string Name[50005],Father[50005];
long long n,cnt=0,Head[50005],f[50005][5],vst[50005],Joy[50005],root;
void AddEdge(long long x,long long y) {
    cnt++;
    Edge[cnt].to=y;
    Edge[cnt].next=Head[x];
    Head[x]=cnt;
}
void TreeDp(long long root) {
    f[root][0]=0;
    f[root][1]=Joy[root];
    for(int i=Head[root]; i; i=Edge[i].next) {
        int Next=Edge[i].to;
        TreeDp(Next);
        f[root][0]=max(f[root][0],max(f[root][0]+f[Next][1],f[root][0]+f[Next][0]));
        f[root][1]=max(f[root][1],f[Next][0]+f[root][1]);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1; i<=n; i++) {
        cin>>Name[i]>>Joy[i]>>Father[i];
        M[Name[i]]=i;
    }
    for(int i=1; i<=n; i++) {
        if(Father[i]=="NOBODY")continue;
        AddEdge(M[Father[i]],M[Name[i]]);
        vst[M[Name[i]]]=1;
    }
    for(int i=1; i<=n; i++)if(!vst[i])root=i;
    TreeDp(root);
    printf("%lld\n",max(f[root][0],f[root][1]));
    return 0;
}

你可能感兴趣的:(树形动规,动规Dp)