Poetize4 创世纪
3037: 创世纪
Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 123 Solved: 66
[Submit][Status]
Description
applepi手里有一本书《创世纪》,里面记录了这样一个故事……
上帝手中有着N 种被称作“世界元素”的东西,现在他要把它们中的一部分投放到一个新的空间中去以建造世界。每种世界元素都可以限制另外一种世界元素,所以说上帝希望所有被投放的世界元素都有至少一个没有被投放的世界元素能够限制它,这样上帝就可以保持对世界的控制。
由于那个著名的有关于上帝能不能制造一块连自己都不能举起的大石头的二律背反命题,我们知道上帝不是万能的,而且不但不是万能的,他甚至有事情需要找你帮忙——上帝希望知道他最多可以投放多少种世界元素,但是他只会O(2^N) 级别的算法。虽然上帝拥有无限多的时间,但是他也是个急性子。你需要帮助上帝解决这个问题。
Input
第一行是一个整数N,表示世界元素的数目。
第二行有 N 个整数A1, A2, …, AN。Ai 表示第i 个世界元素能够限制的世界元素的编号。
Output
一个整数,表示最多可以投放的世界元素的数目。
Sample Input
2 3 1 3 6 5
Sample Output
HINT
样例说明
选择2、3、5 三个世界元素即可。分别有1、4、6 来限制它们。
数据范围与约定
对于30% 的数据,N≤10。
对于60% 的数据, N≤10^5。
对于 100% 的数据,N≤10^6,1≤Ai≤N,Ai≠i。
Source
题目大意:给定一张有向图,每个点有且仅有一条出边,要求若一个点x扔下去,至少存在一个保留的点y,y的出边指向x,求最多扔下去多少个点
首先原题的意思就是支配关系 我们反向考虑 求最少保留的点 要求一个点若扔出去 则必须存在一个保留的点指向它
于是这就是最小支配集 不过由于是有向图 所以一个点要么选择 要么被子节点支配 所以就只剩下2个状态了
设f[x]为以x为根的子树选择x的最小支配集 g[x]为不选择x的最小支配集
然后由于是基环树林 所以我们选择一个环上的点 拆掉它的出边 设这个点为x 出边指向的点为y 讨论
1.若x选择 则y一开始就是被支配状态 g[y]初值为0 求一遍最小支配集
2.若x不选 正常求最小支配集即可
两种情况取最小值计入ans 最后输出n-ans即可
然后说一下我关于这张图的形态的理解:
因为原本每个点只有一个出度,入度不定,然后n条边,就是一个 内向树 (直觉上。。。)(用词不专业,不知道对不对。。。)
然后我们存的时候是反过来存的 存每个点能够被哪几个点支配,这样就成了入度为1,出度不定了,就成了一个外向树
所以我们随便找到环上的一个点,然后就可以遍历到所有点。。。而我们找环的时候是顺着原来的边找的,因为这样在环的分叉上回到环。
而这个过程使得一些点没有被标记,所以在DP的时候还要加标记
一些注释写在代码里:
代码:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 1000000+100
#define maxm 500+100
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
int n,rt,ban,ans,a[maxn],fa[maxn],head[maxn],f[maxn],g[maxn];
bool v[maxn];
struct edge{int go,next;}e[maxn];
inline void dfs(int x)
{
v[x]=;
if(v[a[x]])rt=x;else dfs(a[x]);
}
inline void dp(int x)
{
f[x]=;g[x]=inf;v[x]=;
if(x==ban)g[x]=;
for(int i=head[x];i;i=e[i].next)
if(i!=rt&&e[i].go!=fa[x])
{
int y=e[i].go;
fa[y]=x;
dp(y);
g[x]+=min(f[y],g[y]);
g[x]=min(g[x],f[x]+f[y]-);//这里巧妙的避免了使用临时变量来存储f[y]与g[y]的最小差值
f[x]+=min(f[y],g[y]);
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();int x;
for1(i,n)e[i].go=i,a[i]=x=read(),e[i].next=head[x],head[x]=i;
for1(i,n)
if(!v[i])
{
dfs(i);//找出这棵基环树
ban=a[rt];//选取rt作为x,a[rt]作为y,g[y]=0
dp(rt);
int tmp=f[rt];//限定rt必须选
ban=;
dp(rt);
tmp=min(tmp,g[rt]);//不用选rt
ans+=tmp;
}
printf("%d\n",n-ans);
return ;
}
Poetize4 创世纪的更多相关文章
- 为创世纪图书馆(Library Genesis)作镜像
简介 Library Genesis的Wikipedia条目中的介绍是: Library Genesis or LibGen is a search engine for articles and b ...
- 编程哲学之C#篇:01——创世纪
我们能否像神一样地创建一个世界? 对于创建世界而言,程序员的创作能力最接近于神--相对于导演,作家,漫画家而言,他们创建的世界(作品)一旦完成,就再也不会变化,创建的角色再也不会成长.而程序员创建的世 ...
- 【BZOJ3037/2068】创世纪/[Poi2004]SZP 树形DP
[BZOJ3037]创世纪 Description applepi手里有一本书<创世纪>,里面记录了这样一个故事……上帝手中有着N 种被称作“世界元素”的东西,现在他要把它们中的一部分投放 ...
- [bzoj3037/2068]创世纪[Poi2004]SZP_树形dp_并查集_基环树
创世纪 SZP bzoj-3037/2068 Poi-2004 题目大意:给你n个物品,每个物品可以且仅可以控制一个物品.问:选取一些物品,使得对于任意的一个被选取的物品来讲,都存在一个没有被选取的物 ...
- CH6401 创世纪
6401 创世纪 0x60「图论」例题 描述 上帝手中有 N(N≤10^6) 种世界元素,每种元素可以限制另外1种元素,把第 i 种世界元素能够限制的那种世界元素记为 A[i].现在,上帝要把它们中的 ...
- 图形学创世纪——写在SIGGRAPH 40年的边上
40年的边上" title="图形学创世纪--写在SIGGRAPH 40年的边上"> 前言: SIGGRAPH是由ACM SIGGRAPH(美国计算机协会计算机图形 ...
- JZOJ 3929. 【NOIP2014模拟11.6】创世纪
3929. [NOIP2014模拟11.6]创世纪 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 上帝手 ...
- T1创世纪(原创)
创世纪 这是我的第一道原创题 题解: 这道题的核心算法是:加维度的最短路+贪心 状态:\(dis[i][j][t][a]\)表示在 \(t\) 时,到达 \((i,j)\) ,当前共造\(a\)只&q ...
- 「Poetize4」创世纪
在tyvj上怀疑爆栈了.....或许一定是我写挂了.以后调吧... UPD:bzoj上过了... 题解:https://blog.csdn.net/popoqqq/article/details/39 ...
随机推荐
- xslt语法之---基础语法
1. XSLT常用元素: 1.1 <xsl:template>:创建模板 Match属性的作用是使模板和XML元素相关联 <xsl:template match=" ...
- node.js中文资料导航
以下资料来自gitHUb上面:https://github.com/youyudehexie/node123 Node.js HomePage Node官网七牛镜像 Infoq深入浅出Node.js系 ...
- Java Socket 学习笔记
TCP协议的Socket编程 Socket:英文中的意思是插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket.Java中所有关于网络编程的类都 ...
- 我是一块cpu 《转载》
我是一块cpu,原装intel,在一台普通的台式计算机里供职.我有个小弟是内存,我要靠他时时刻刻陪伴我工作,其实有时候我并不是没有某某地址的资料,而是懒得翻--麻烦. 还有一个老大哥叫bios,每次那 ...
- java编程思想-异常
DynamicFields类的setField方法里面的getField方法抛出的异常NoSuchFieldException 为什么是throw new RuntimeException(e);
- Linux运行C#程序
首先需要安装mono 安装教程http://www.cnblogs.com/aixunsoft/p/3422099.html 然后 用终端执行C#程序就可以了,mono 程序文件名 可以直接执行win ...
- Opencart 之 Registry 类详解
Registry 中文意思是记录,登记,记录本的意思, 在opencart中他的用途就是 登记公共类.类的原型放在 system\engine文件夹下 代码很简单: <?php final cl ...
- 用java写bp神经网络(二)
接上篇. Net和Propagation具备后,我们就可以训练了.训练师要做的事情就是,怎么把一大批样本分成小批训练,然后把小批的结果合并成完整的结果(批量/增量):什么时候调用学习师根据训练的结果进 ...
- NSDate和NSString的转换及判定是昨天,今天,明天
用于uidate,picker.. +(NSDate*) convertDateFromString:(NSString*)uiDate{ NSDateFormatter *formatter ...
- 最简单的基于FFmpeg的推流器(以推送RTMP为例)
===================================================== 最简单的基于FFmpeg的推流器系列文章列表: <最简单的基于FFmpeg的推流器(以 ...