tyvj1940创世纪——贪心(基环树)
题目:http://www.joyoi.cn/problem/tyvj-1940
基环树的样子,看了书上的讲解,准备写树上DP,然后挂了:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- int const MAXN=1e6+,inf=1e9;
- int n,a[MAXN],f[MAXN][],head[MAXN],ct,s[MAXN],h,col[MAXN],cr,rt,ans;
- int sta[MAXN],top,reg[MAXN];
- bool in[MAXN],fl,vis[MAXN];
- struct N{
- int to,next;
- N(int t=,int n=):to(t),next(n) {}
- }edge[MAXN];
- void add(int x,int y)
- {
- edge[++ct]=N(y,head[x]);head[x]=ct;
- edge[++ct]=N(x,head[y]);head[y]=ct;
- }
- void ser(int x)
- {
- col[x]=cr;
- for(int i=head[x],u;i;i=edge[i].next)
- if(!col[u=edge[i].to])ser(u);
- }
- void tj(int rt,int x)
- {
- if(fl)return;
- sta[++top]=x;vis[x]=;
- for(int i=head[x],u;i;i=edge[i].next)
- {
- if(edge[i].to==a[x])continue;
- if(!vis[u=edge[i].to])tj(rt,u);
- else
- {
- while(sta[top]!=rt)
- {
- int t=sta[top];
- s[++h]=t;
- in[t]=;top--;
- }
- in[rt]=;s[++h]=rt;top--;
- fl=;return;
- }
- }
- top--;
- }
- void dfs(int x)
- {
- int mn=inf,sum=;
- for(int i=head[x],u;i;i=edge[i].next)
- {
- u=edge[i].to;
- if(u==rt)continue;
- if(u==a[x]||col[u]!=col[x])continue;
- dfs(u);
- f[x][]+=max(f[u][],f[u][]);
- sum+=f[u][];
- mn=min(mn,f[u][]-f[u][]);
- }
- if(sum==)f[x][]=;
- else f[x][]=sum-mn;
- }
- void dfs2(int x)
- {
- int mn=inf,sum=;
- for(int i=head[x],u;i;i=edge[i].next)
- {
- u=edge[i].to;
- if(u==rt)continue;
- if(u==a[x]||col[u]!=col[x])continue;
- dfs(u);
- f[x][]+=max(f[u][],f[u][]);
- sum+=f[u][];
- mn=min(mn,f[u][]-f[u][]);
- }
- if(sum==)f[x][]=;
- else if(x==a[rt])f[x][]=sum;
- else f[x][]=sum-mn;
- }
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- {
- scanf("%d",&a[i]);
- reg[i]++;reg[a[i]]++;
- add(i,a[i]);
- }
- for(int i=;i<=n;i++)
- {
- if(!col[i])h=,cr++,ser(i);
- int rt;fl=;int s=;
- for(int j=;j<=n;j++)
- if(reg[j]>&&col[j]==cr)
- {rt=j;break;}
- tj(rt,i);
- dfs(rt);
- s=max(f[rt][],f[rt][]);
- dfs2(rt);
- s=max(s,f[rt][]);
- ans+=s;
- }
- printf("%d",ans);
- return ;
- }
无输出的冗长树上DP
题目挺有意思,自己本来也想过贪心的做法,但不会处理链与环交接处的问题,想不清楚一条链会对环有什么影响;
然后看了看别人的博客,才发现链对环没有影响。。。因为环上的点不论链上怎样,仍还有环上别的点限制它;
所以链与环都是隔一个选一个,贪心。
代码如下:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<queue>
- using namespace std;
- queue<int>q;
- int const MAXN=1e6+;
- int n,a[MAXN],reg[MAXN],ans;
- bool vis[MAXN],v2[MAXN];
- void bfs()
- {
- for(int i=;i<=n;i++)
- if(!reg[i])q.push(i);
- while(q.size())
- {
- int x=q.front();q.pop();
- vis[x]=;
- if(!vis[a[x]])
- {
- ans++;//因为多起点开始,不方便直接求链的长度,所以一个一个加
- vis[a[x]]=;
- reg[a[a[x]]]--;
- if(!reg[a[a[x]]]&&!vis[a[a[x]]])
- q.push(a[a[x]]);
- }
- }
- }
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- {
- scanf("%d",&a[i]);
- reg[a[i]]++;
- }
- bfs();
- for(int i=;i<=n;i++)
- if(!vis[i]&&!v2[i])
- {
- int cnt=;v2[i]=;
- int j=a[i];
- while(!v2[j])cnt++,j=a[j];
- ans+=cnt/;
- }
- printf("%d",ans);
- return ;
- }
tyvj1940创世纪——贪心(基环树)的更多相关文章
- BZOJ3037 创世纪(基环树DP)
基环树DP,攻的当受的儿子,f表选,g表不选.并查集维护攻受关系.若有环则记录,DP受的后把它当祖宗,再DP攻的. #include <cstdio> #include <iostr ...
- [bzoj3037/2068]创世纪[Poi2004]SZP_树形dp_并查集_基环树
创世纪 SZP bzoj-3037/2068 Poi-2004 题目大意:给你n个物品,每个物品可以且仅可以控制一个物品.问:选取一些物品,使得对于任意的一个被选取的物品来讲,都存在一个没有被选取的物 ...
- BZOJ3037 创世纪[基环树DP]
实际上基环树DP的名字是假的.. 这个限制关系可以看成每个点有一条出边,所以就是一个内向基环树森林. 找出每个基环树的环,然后对于树的部分,做DP,设状态选或不选为$f_{x,0/1}$,则 $f_{ ...
- luogu3651 展翅翱翔之时 (はばたきのとき)[基环树+贪心]
考前随便做点水题愉♂悦身心 有助于退役 这题意思其实就是说要把外向基环树森林改成一个环的最小代价. 依照套路,先对每棵基环树的树做dp,这里因为要是环,要把所有的树都拆成链,然后连接.所以考虑以最小代 ...
- Solution -「基环树」做题记录
写的大多只是思路,比较简单的细节和证明过程就不放了,有需者自取. 基环树简介 简单说一说基环树吧.由名字扩展可得这是一类以环为基础的树(当然显然它不是树. 通常的表现形式是一棵树再加一条非树边,把图画 ...
- Poetize4 创世纪
3037: 创世纪 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 123 Solved: 66[Submit][Status] Description ...
- 【BZOJ3037/2068】创世纪/[Poi2004]SZP 树形DP
[BZOJ3037]创世纪 Description applepi手里有一本书<创世纪>,里面记录了这样一个故事……上帝手中有着N 种被称作“世界元素”的东西,现在他要把它们中的一部分投放 ...
- JZOJ 3929. 【NOIP2014模拟11.6】创世纪
3929. [NOIP2014模拟11.6]创世纪 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 上帝手 ...
- 与图论的邂逅01:树的直径&基环树&单调队列
树的直径 定义:树中最远的两个节点之间的距离被称为树的直径. 怎么求呢?有两种官方的算法(不要问官方指谁我也不晓得): 1.两次搜索.首先任选一个点,从它开始搜索,找到离它最远的节点x.然后从x开始 ...
随机推荐
- Debian Customer PPA RFC (by quqi99)
作者:张华 发表于:2016-01-13版权声明:能够随意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) Pre ...
- SD卡操作相关的工具SDCardUtils
SD卡操作相关的工具 package com.flyou.utils; import java.io.File; import android.os.Environment; import andro ...
- Android自己定义控件
今天我们来讲一下 Android中自己定义控件的介绍,在Android中, 我们一般写xml都是用的是单个的控件来完毕的 ,但是.往往在一些项目中.单个控件有时是满足不了的.故此我们能够自己定义控件 ...
- DataSource是什么
public interface DataSource 该工厂用于提供到此 DataSource 对象表示的物理数据源的连接.作为 DriverManager(二者区别:http://tobylxy. ...
- iOS GCD使用
Grand Central Dispatch(GCD)是异步运行任务的技术之中的一个. 一般将应用程序中记述的线程管理用的代码在系统级中实现.开发人员仅仅须要定义想运行的任务并追加到适当的Dispat ...
- 【HDOJ 5371】 Hotaru's problem
[HDOJ 5371] Hotaru's problem Manacher算法+穷举/set Manacher算法一好文:http://blog.csdn.net/yzl_rex/article/de ...
- oracle insert/update
insert into table (,,) values (,,) where update table set (,)=(select , from ) where
- http://www.cnblogs.com/yycxbjl/archive/2010/04/20/1716689.html
http://www.cnblogs.com/yycxbjl/archive/2010/04/20/1716689.html PS: 开发工具 VS2010, 所有工程都为Debug状态,本人刚接触 ...
- ARM architecture
http://en.wikipedia.org/wiki/ARM_architecture ARM architecture ARM architectures The ARM logo De ...
- 在Linux的Eclipse下搭建Android环境
http://blog.csdn.net/lyonte/article/details/6407242 一.Java环境安装配置详见<在Linux下搭建Java环境>http://blog ...