Party

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0

Problem Description
  B公司共有N个员工,但是并不是所有人都能和睦相处。在每一个人的心中都有一个潜在的对手,任何人都不能接受和他的对手同时参加B公司的聚餐。然而这种关系并不一定是对称的,也就是说,A把B视作自己的对手,而B所想的对手并不一定是A。
  现在,B公司准备举办一次盛大的聚会,公司希望员工通过这次聚会获得尽可能多的快乐值。第i个员工的快乐值是一个大于0不大于100的整数,如果他参加聚餐,他就会获得的快乐值,如果他的对手参加聚餐,他的快乐值就为0。
  但老板在安排聚餐时不知道如何解决这个问题,因此,他找到你帮忙计算这次聚会最多可以带来多少快乐值。
 
Input
  输入数据的第一行是一个整数T,表示有T组测试数据。
  每组数据的第一行包括一个整数N,表示共有N个员工。(约有500组数据N不大于500,约有10组数据N不大于100000)
  第二行是N个用空格隔开的整数,第i个整数表示第i个员工的对手的编号。数据保证 xi ∈ [1,N], 且 xi <> i .
  第三行也包含N个用空格隔开的整数,表示第i个员工能够获得的快乐值ai
 
Output
  对于第k组数据,第一行输出Case #k:,第二行输出仅包含一个数,表示这次聚会最多可以带来多少快乐值。
 
Sample Input
1
8
2 7 1 8 4 2 3 5
50 30 40 40 50 10 70 60
 
Sample Output
Case #1:
190

Hint

在样例中,应选择1、6、7、8号员工。

解题报告:
将每个员工认为是图上的一个顶点,如果员工s的敌人是员工t,则s到t建立一条有向边。由于每个员工只有一个敌人,因此每个顶点的出度为1。所以整个图可以被拆分成多个连通子图,每个联调子图上只有一个环,可以分别对每个连通子图单独处理。
         考虑每个连通子图,找出环上的任意一条边s->t,去除这条边后,可以得到以s为根的一颗树,然后枚举t被选择或者不被选择的情况,分别做一轮树形DP。
假设dp[k][0]表示在节点k不被选择的情况下,以节点k为根节点的子树下能够选择出来的最大快乐值;dp[k][1]则表示节点k被选择的情况。那么可以得到
dp[k][0] = sum( max( dp[son][0], dp[son][1] ) ) (son是节点k的儿子节点)
dp[k][1] = sum( dp[son][0] ) + happy[k] (happy[k]表示节点k能够获得的快乐值)
         当t被选择情况下 max_value1= dp[0];当t不被选择情况下max_value2=
max(dp[0], dp[1]);而每个连通子图的最优解是max(max_value1,max_value2)
         整体处理的时间复杂度为O(N)

解题代码:

#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<queue> using namespace std; const int N = ; int val[N],ru[N],vis[N],res[N][];
vector<int>edge[N];
queue<int>que; int main()
{
int T = ;
int csnum;
scanf("%d",&csnum);
for(int cs=;cs<=csnum;cs++)
{
int n;
scanf("%d",&n); for(int i=;i<=n;i++)
{
edge.clear();
ru=;
vis=;
}
while(que.empty()==false)
que.pop(); for(int i=;i<=n;i++)
{
int a;
scanf("%d",&a);
edge.push_back(a);
edge[a].push_back(i);
ru++;ru[a]++;
}
for(int i=;i<=n;i++)
{
scanf("%d",&val);
res[]=val;
res[]=;
} for(int i=;i<=n;i++)
{
if(ru==)
que.push(i);
} while(que.empty()==false)
{
int x=que.front();
que.pop();
vis[x]=;
for(int i=;i<edge[x].size();i++)
{
int y=edge[x];
if(vis[y]==)
{
ru[y]--;
if(ru[y]==)
que.push(y); res[y][]+=res[x][];
res[y][]+=max(res[x][],res[x][]);
}
}
} int ans=;
for(int i=;i<=n;i++)
{
if(vis==)
{
int rs[][];
rs[][]=rs[][]=rs[][]=res[];
rs[][]=res[];
int pre=i;
vis=; do{
int x=-;
for(int j=;j<edge[pre].size();j++)
{
x=edge[pre][j];
if(vis[x]==)
break;
}
// printf("%d-%d ",pre,x);
// puts("");
if(vis[x]==)
break;
vis[x]=; int nrs[][];
for(int u=;u<;u++)
{
nrs[]=max(rs[],rs[])+res[x][];
nrs[]=rs[]+max(res[x][],res[x][]);
}
for(int u=;u<;u++)
for(int v=;v<;v++)
rs[v]=nrs[v];
pre=x;
}while(true); int a=max(rs[][],rs[][]);
int b=rs[][];
ans+=max(a,b);
// printf("%d %d\n",i,max(a,b));
}
}
printf("Case #%d:\n%d\n", T++, ans);
}
return ;
}

2014百度之星 Party的更多相关文章

  1. 2014百度之星预赛(第二场)——Best Financing

    2014百度之星预赛(第二场)--Best Financing Problem Description 小A想通过合理投资银行理財产品达到收益最大化.已知小A在未来一段时间中的收入情况,描写叙述为两个 ...

  2. 2014百度之星资格赛——Disk Schedule

    2014百度拥有明星格比赛--Disk Schedule Problem Description 有非常多从磁盘读取数据的需求,包含顺序读取.随机读取. 为了提高效率.须要人为安排磁盘读取. 然而.在 ...

  3. 2014百度之星初赛第二场hdu 4831 Scenic Popularity

    Scenic Popularity Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  4. 2014 百度之星 题解 1004 Labyrinth

    Problem Description 度度熊是一仅仅喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫仅仅能从矩阵左上角第一个方格開始走,仅仅有走到右上角的第一个格子才算走出迷宫,每一次仅仅能 ...

  5. 2014百度之星资格赛 1004:Labyrinth(DP)

    Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  6. 2014百度之星资格赛 1001:Energy Conversion(水题,逻辑题)

    Energy Conversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. 2014 百度之星题解 1002 - Disk Schedule

    Problem Description 有非常多从磁盘读取数据的需求,包含顺序读取.随机读取.为了提高效率,须要人为安排磁盘读取.然而,在现实中,这样的做法非常复杂.我们考虑一个相对简单的场景. 磁盘 ...

  8. 2014百度之星第四题Labyrinth(DP)

    Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. 2014百度之星第三题Xor Sum(字典树+异或运算)

    Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total ...

  10. HDU4828 Grids 2014百度之星预赛问题解决

    看看Catalan数的公式:为 Catalan(n) = C(2n, n) / n+1 = C(2n, n) - C(2n, n-1); (公式0) 然后利用全排序表达:Catalan(n) = (2 ...

随机推荐

  1. English--音标重难点

    English|音标重难点 在拥有了,音标的元音与辅音的基础之后,需要对于这些音标进行加以区分,毕竟方言对于口型的影响非常的大. 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...

  2. git远程写协作同步

    1:创建一个要提交的文件2 git init 初始化 3 git remote add origin https://github.com/maohongli/cang.git 建立远程连接4 git ...

  3. MySQL查询——select

    SELECT select的完整语法: select col1, col2,... # 业务查询的字段 from table_name # 选取的哪张表 [where single_condition ...

  4. 用node发布一个包

    手把手教你用npm发布一个包 注:本文引用于简书 http://www.jianshu.com/p/36d3e0e00157   但是内容的话,还是一样的,也就是继续之前的工作,将那个autoRout ...

  5. vue+element 表格按需合并

    这个功能难度感觉一般般吧,记录一下,以后碰到了直接来复制,懒得再写了 效果如下: 前6列是合并,后面的有几行,动态显示几行 重点是在数据处理上面做文章,合并列大家都会,数据处理呢?这样来处理, 我们拿 ...

  6. leetcode 学习心得 (4)

    645. Set Mismatch The set S originally contains numbers from 1 to n. But unfortunately, due to the d ...

  7. Vue axios异步获取后台数据alert提示undefined

    记录一个小问题,关于分页查询套餐 前台通过axios异步请求获取后台数据alert弹出数据提示undefined 下面有三个bean PageResult /** * 分页结果封装对象 */ publ ...

  8. NameNode && Secondary NameNode工作机制

    NameNode && Secondary NameNode工作机制 1)工作流程 2)  fsimage和edits NameNode是HDFS的大脑,它维护着整个文件系统的目录树, ...

  9. 解决使用maven clean项目的时候报错,删除target文件夹失败

    背景:jdk1.8 + maven3.5.2 问题描述: 我在使用maven clean项目的时候,celan 失败,报错的原因是删除项目下的target文件夹下面的文件失败 解决方法: 打开任务管理 ...

  10. Linux shell简单创建用户脚本

    前面介绍简单的shell编写规则. 现在开始编写一个简单的shell脚本. Linux shell介绍 编写shell脚本    1.创建脚本文件    2.根据需求,编写脚本    3.测试执行脚本 ...