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. Jenkins配置HTML报告(Windows环境)

    1.首先安装插件HTML Publisher,点击直接安装 2.在任务中配置,构建后操作,添加Publish HTML reports 3.添加完成后,新增一项 4.HTML directory to ...

  2. 《opencv学习》 之 OTSU算法实现二值化

    主要讲解OTSU算法实现图像二值化:    1.统计灰度级图像中每个像素值的个数. 2.计算第一步个数占整个图像的比例. 3.计算每个阈值[0-255]条件下,背景和前景所包含像素值总个数和总概率(就 ...

  3. ldap复制

    1.使用yum命令安装openldap,openldap-servers,openldap-clients $ yum install openldap $ yum install openldap- ...

  4. 4. java乱码处理

    //返回到jsp页面 //request.setCharacterEncoding("utf-8"); //response.setContentType("text/h ...

  5. Mybatis like模糊查询的写法

    转自:http://blog.51cto.com/lavasoft/1386870 Mybatis like查询官方文档没有明确的例子可循,网上搜索了很多,都不正确. Mybatis 3.2.6经过尝 ...

  6. S+ hidden tray with window start

    官方论坛上有个帖子给出了答案: I forgot that this is supported in the code, but it requires a little editing of the ...

  7. 3 Python 函数介绍

    1.函数的基本概念 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 语法定义 def ...

  8. UI5-文档-2.3-使用SAPUI5工具为Eclipse开发应用程序

    用于为简单用例开发应用程序.用于Eclipse的SAPUI5应用程序开发工具提供向导来支持您以一种简单的方式创建应用程序.使用application project向导,将自动创建包含视图和控制器的必 ...

  9. eclipse从svn导入maven项目变成普通项目解决办法

    右击项目-->configure-->Convert to Maven Project

  10. Python Spider 抓取今日头条街拍美图

    """ 抓取今日头条街拍美图 """ import os import time import requests from hashlib ...