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. 20180129周一之学习PYTHON笔记【PYTHON2写个自动点击学习功能】

    pyautogui.click(pyautogui.center(pyautogui.locateOnScreen('sy.png'))) #点击该截图一次 --------------------- ...

  2. 可视化学习Tensorboard

    可视化学习Tensorboard TensorBoard 涉及到的运算,通常是在训练庞大的深度神经网络中出现的复杂而又难以理解的运算.为了更方便 TensorFlow 程序的理解.调试与优化,发布了一 ...

  3. Tensorflow线程和队列

    读取数据 小数量数据读取 这仅用于可以完全加载到存储器中的小的数据集有两种方法: 存储在常数中. 存储在变量中,初始化后,永远不要改变它的值. 使用常数更简单一些,但是会使用更多的内存,因为常数会内联 ...

  4. uva-10152-乌龟排序

    求从待排序的到期望的顺序的最小操作顺序,只能进行一个操作,将当前的乌龟拿出来,上面的下移,拿出来的放到最上面 发现voj没有PE, 解题方法,把俩个串反过来使用,从期望的顺序到待排序的顺序. AC:1 ...

  5. C_point指针

    1,关于C语言中变量的访问方式,直接访问[使用变量名直接引用,操作变量进行赋值,改变变量值等操作],间接访问--指针,一种指向变量飞, 程序对变如量的读写操作,实际是对变量所在的存储空间进行写入和取出 ...

  6. VBA 禁止保存

    禁止保存 在workbook事件中 Private Sub Workbook_BeforeClose(Cancel As Boolean)    Me.Saved = TrueEnd Sub Priv ...

  7. Maven 项目中 添加自己的jar包

    mvn install:install-file   -Dfile=java-bloomfilter-1.0.jar  -DgroupId=com.sina  -DartifactId=java-bl ...

  8. SOA和微服务到底是什么关系

    本文原创,原文地址为:http://www.cnblogs.com/fengzheng/p/5847441.html SOA和微服务到底是什么关系? 说实话,我确实不明白SOA和微服务到底有什么本质上 ...

  9. Java并发测试

    要求:模拟200个设备,尽量瞬间并发量达到200. 思路 第一种:线程池模拟200个线程——wait等待线程数达200——notifyAll唤醒所有线程 第二种:线程池模拟200个线程——阻塞线程—— ...

  10. HIBERNATE知识复习记录4-HQL和QBC

    Hibernate中共提供了三种检索方式:HQL(Hibernate Query Language).QBC.QBE(Query By Example). HQL 是Hibernate Query L ...