Description:

上帝手中有着 N 种被称作“世界元素”的东西,现在他要把它们中的一部分投放到一个新的空间中去以建造世界。每

种世界元素都可以限制另外一种世界元素,所以说上帝希望所有被投放的世界元素都有至少一个没有被投放的世界元素
能够限制它,这样上帝就可以保持对世界的控制。由于那个著名的有关于上帝能不能制造一块连自己都不能举起的大石头的二律背反命题,我们知道上帝不是万能的,而且不
但不是万能的,他甚至有事情需要找你帮忙——上帝希望知道他最多可以投放多少种世界元素,但是他只会 O(2N) 级别的算法。虽然上帝拥有无限多的时间,但是他也是个急性子。
你需要帮助上帝解决这个问题。

Input:

第一行是一个整数 N,表示世界元素的数目。
  第二行有 N 个整数 A1, A2, …, AN。Ai 表示第 i 个世界元素能够限制的世界元素的编号。

Output:

一个整数,表示最多可以投放的世界元素的数目。

思路:先找环,跑两次树形DP,一次断开,一次重连

然后本机上用光盘里的数据+手动扩栈过了……codevs上因为不能扩栈结果爆栈了……还是我树形DP写得太差了

#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int N = 1e6 + ;
int n, sz, a[N], dp[N][], dp2[N][], deg[N], fa[N], pre[N], dfn[N], c[N];
vector<int> cir;
bool vis[N]; int head[N], now = ;
struct edges{
int to, next, f;
}edge[N<<];
void add(int u, int v){
edge[++now].to = v, edge[now].next = head[u], edge[now].f = ; head[u] = now;
edge[++now].to = u, edge[now].next = head[v], edge[now].f = ; head[v] = now;
}
int get(int x){
if(x != fa[x]) return fa[x] = get(fa[x]);
return x;
}
void Merge(int x,int y){
x = get(x), y = get(y);
if(x != y) fa[y] = x;
} void fcur(int x){
dfn[x] = ++sz;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(v == pre[x]) continue;
if(dfn[v]){
if(dfn[v] < dfn[x]) continue;
cir.push_back(x); c[x] = ;
for(; x != v; v = pre[v]) c[v] = , cir.push_back(v);
}else pre[v] = x, fcur(v);
}
return ;
}
void dfs2(int x){
dp[x][] = ;
bool flag = ;
int pos = , mn = 1e9;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(edge[i].f) continue;
flag = ;
dfs2(v);
dp[x][] += max(dp[v][], dp[v][]);
if(dp[v][] - dp[v][] < mn){
mn = dp[v][] - dp[v][];
pos = v;
}
}
if(flag) dp[x][]++;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(edge[i].f) continue;
if(v == pos) dp[x][] += dp[v][];
else dp[x][] += max(dp[v][], dp[v][]);
}
return ;
}
void dfs3(int x){
dp2[x][] = ;
bool flag = ;
int pos = , mn = 1e9;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(edge[i].f) continue;
flag = ;
dfs3(v);
dp2[x][] += max(dp2[v][], dp2[v][]);
if(dp2[v][] - dp2[v][] < mn){
mn = dp2[v][] - dp2[v][];
pos = v;
}
}
if(x == a[cir[]]){ //如果找到能强制重连的点
dp2[x][]++;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(edge[i].f) continue;
dp2[x][] += max(dp2[v][], dp2[v][]);
}
return ;
}
if(flag) dp2[x][]++;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(edge[i].f) continue;
if(v == pos) dp2[x][] += dp2[v][];
else dp2[x][] += max(dp2[v][], dp2[v][]);
}
return ;
}
void DP(){
for(int i = head[cir[]]; i; i = edge[i].next)
if(c[edge[i].to] && edge[i].f){ //先断开环上两个点的关系
edge[i ^ ].f = ;
break;
}
dfs2(cir[]);
dfs3(cir[]); //带上强制重连的点DP
dp[cir[]][] = max(dp[cir[]][], dp2[cir[]][]); //更新关系
}
int main(){
int size = << ;
char*p=(char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p) );
// freopen("gen.in","r",stdin);
// freopen("gen.out","w",stdout);
scanf("%d", &n);
for(int i = ; i <= n; i++) fa[i] = i;
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
add(i, a[i]); Merge(i, a[i]);
}
int ans = ;
for(int i = ; i <= n; i++){ //对于每个联通块找环后DP
int x = get(i);
if(!vis[x]){
cir.clear();
vis[x] = , fcur(i);
// for(int i = 0; i < cir.size(); i++) cout<<cir[i]<<" "; cout<<endl;
DP();
ans += max(dp[cir[]][], dp[cir[]][]);
}
}
printf("%d\n", ans);
return ;
}

在这里插一个基环树找环的代码(适用于无向基环树)

void fcur(int x){
dfn[x] = ++sz;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(v == pre[x]) continue;
if(dfn[v]){
if(dfn[v] < dfn[x]) continue;
cir.push_back(x); c[x] = ;
for(; x != v; v = pre[v]) c[v] = , cir.push_back(v);
}else pre[v] = x, fcur(v);
}
return ;
}

TYVJ 1940 创世纪的更多相关文章

  1. Poetize4 创世纪

    3037: 创世纪 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 123  Solved: 66[Submit][Status] Description ...

  2. 为创世纪图书馆(Library Genesis)作镜像

    简介 Library Genesis的Wikipedia条目中的介绍是: Library Genesis or LibGen is a search engine for articles and b ...

  3. 编程哲学之C#篇:01——创世纪

    我们能否像神一样地创建一个世界? 对于创建世界而言,程序员的创作能力最接近于神--相对于导演,作家,漫画家而言,他们创建的世界(作品)一旦完成,就再也不会变化,创建的角色再也不会成长.而程序员创建的世 ...

  4. 【BZOJ3037/2068】创世纪/[Poi2004]SZP 树形DP

    [BZOJ3037]创世纪 Description applepi手里有一本书<创世纪>,里面记录了这样一个故事……上帝手中有着N 种被称作“世界元素”的东西,现在他要把它们中的一部分投放 ...

  5. [bzoj3037/2068]创世纪[Poi2004]SZP_树形dp_并查集_基环树

    创世纪 SZP bzoj-3037/2068 Poi-2004 题目大意:给你n个物品,每个物品可以且仅可以控制一个物品.问:选取一些物品,使得对于任意的一个被选取的物品来讲,都存在一个没有被选取的物 ...

  6. CH6401 创世纪

    6401 创世纪 0x60「图论」例题 描述 上帝手中有 N(N≤10^6) 种世界元素,每种元素可以限制另外1种元素,把第 i 种世界元素能够限制的那种世界元素记为 A[i].现在,上帝要把它们中的 ...

  7. 图形学创世纪——写在SIGGRAPH 40年的边上

    40年的边上" title="图形学创世纪--写在SIGGRAPH 40年的边上"> 前言: SIGGRAPH是由ACM SIGGRAPH(美国计算机协会计算机图形 ...

  8. JZOJ 3929. 【NOIP2014模拟11.6】创世纪

    3929. [NOIP2014模拟11.6]创世纪 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 上帝手 ...

  9. T1创世纪(原创)

    创世纪 这是我的第一道原创题 题解: 这道题的核心算法是:加维度的最短路+贪心 状态:\(dis[i][j][t][a]\)表示在 \(t\) 时,到达 \((i,j)\) ,当前共造\(a\)只&q ...

随机推荐

  1. 听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构

    转自:https://baijiahao.baidu.com/s?id=1600174787011483381&wfr=spider&for=pc 微服务架构是互联网很热门的话题,是互 ...

  2. web.py尝试性学习!

    首先导入web.py模块! import web 没有的话就: pip install web web.py的URL结构: urls = ( '/', "index" ) 第一部分 ...

  3. ORM介绍(字段 和 字段的参数)

    ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  4. Android手机图片路径

    H:\dcim\100MEDIA H:\Tencent\MobileQQ\photo H:\Tencent\MobileQQ\photo H:\Tencent\MobileQQ\thumb H:\Te ...

  5. YII assets使用

    为什么用YII assets 1.assets的作用是方便模块化,插件化的,一般来说出于安全原因不允许通过url访问protected下面的文件 ,但是我们又希望将module单独出来,所以需要使用发 ...

  6. Spring boot profile 多环境配置

    1.多Profile文件 我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml 默认使用application.properties的配置 ...

  7. mysql find_in_set排序

    假若有给定id数组(1,9,3,5,6);查询sql语句需要安装这个顺序排序 select * from tb where id in (1,9,3,5,6) order by find_in_set ...

  8. Simple2D-14(音乐播放器)简介

    接下来文章中,会介绍一个简单的程序——音乐播放器.通过编写一个音乐播放器在 Simple2D 中加入两个库:音频库 bass 和界面库 ImGui. 下面是音乐播放器的预览图: 播放器的功能比较简单, ...

  9. svn更新代码时控制台出现的英文字母表示什么意思

    U:表示从服务器收到文件更新了 G:表示本地文件以及服务器文件都已经更新,而且成功的合并了 A:表示有文件或者目录添加到工作目录 R:表示文件或者目录被替换了 C:表示文件的本地修改和服务器修改发生冲 ...

  10. javascript事件之鼠标滚轮(mousewheel)和DOMMouseScroll事件

    javascript事件之鼠标滚轮(mousewheel)和DOMMouseScroll事件 发布时间:2015-02-07   编辑:www.jquerycn.cn 本文学习下,javascript ...