洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)
题目链接
随机化 暴力:
随便从一个点开始DFS,每次从之前得到的f[i]最大的子节点开始DFS。f[i]为从i开始(之前)能得到的最大答案。
要注意的是f[i]应当有机会从更小的答案更新,
9.10求直径。
就82分了。
本来想的SPFA啥的也不对。。正解思路是这的。
#include <ctime>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=10005,M=2e4+5;int n,m,Max,pos,A[N],Enum,H[N],nxt[M],to[M],f[N];
bool vis[N];
std::vector<int> ans,tmp,ANS;inline int read()
{int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now;
}
inline void AddEdge(int u,int v){to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS(int x)
{vis[x]=1, tmp.push_back(x);int way=0;for(int i=H[x]; i; i=nxt[i])if(!vis[to[i]]&&f[way]<f[to[i]]) way=to[i];if(way) DFS(way);
}
void Solve()
{memset(f,0,sizeof f);for(int t=500; t; --t)for(int i=1; i<=n; ++i){memset(vis,0,sizeof vis), tmp.clear(), DFS(i);if(tmp.size()>ans.size()) ans=tmp;
// if(tmp.size()>f[i]) f[i]=tmp.size();if(tmp.size()>f[i]||rand()%15==0) f[i]=tmp.size();}if(ans.size()>ANS.size()) ANS=ans;
}
namespace Spec
{int Max,v,pre[N];void DFS(int x,int f,int d){if(d>Max) Max=d, v=x;for(int i=H[x]; i; i=nxt[i])if(to[i]!=f) pre[to[i]]=x, DFS(to[i],x,d+1);}void Solve(){Max=0, DFS(1,1,1);int u=v;Max=0, DFS(v,v,1);printf("%d\n%d\n",Max,v);while(v!=u) printf("%d\n",v=pre[v]);}
}int main()
{
// freopen("guide.in","r",stdin);
// freopen("guide.out","w",stdout);srand(time(NULL));n=read(),m=read();for(int i=1; i<=m; ++i) AddEdge(read(),read());
// Spec::Solve(); return 0;//9.10for(int T=1; T<=15; ++T) Solve();printf("%d\n",ANS.size());for(int i=0; i<ANS.size(); ++i) printf("%d\n",ANS[i]);return 0;
}
正解:
可以先随机生成一棵树,然后去求它的直径。
想要这棵树的直径尽量大,它上面的点的度数应尽量小(要不大概就是很多分叉那样)。
枚举/随机一个根节点x,从它开始DFS,每次优先走度数最小的点v(注意把它相连的点的度数-1),连树上的边x->v。
DFS完这个度数最小的点v后,可以从x再走其它未访问的点,扩展树。
#include <ctime>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=10005,M=2e4+5;int n,m,Max,V,pre[N],Enum,H[N],nxt[M],to[M],_Enum,_H[N],_nxt[M],_to[M],Dgr[N],dgr[N],ans[N];
bool vis[N];inline int read()
{int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now;
}
inline void AddEdge(int u,int v){++Dgr[u], to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;++Dgr[v], to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
inline void AddTree(int u,int v){_to[++_Enum]=v, _nxt[_Enum]=_H[u], _H[u]=_Enum;_to[++_Enum]=u, _nxt[_Enum]=_H[v], _H[v]=_Enum;
}
void Build(int x)
{vis[x]=1;int way=0;for(int i=H[x]; i; i=nxt[i]) --dgr[to[i]];for(int i=H[x]; i; i=nxt[i])if(!vis[to[i]]&&(dgr[way]>dgr[to[i]]||(dgr[way]==dgr[to[i]]&&rand()&1))) way=to[i];
// if(!vis[to[i]]&&dgr[way]>dgr[to[i]]) way=to[i];//略不对 if(way) AddTree(x,way), Build(way);for(int i=H[x]; i; i=nxt[i])if(!vis[to[i]]) AddTree(x,to[i]), Build(to[i]);
}
void DFS(int x,int f,int d)
{if(d>Max) Max=d, V=x;for(int i=_H[x]; i; i=_nxt[i])if(_to[i]!=f) pre[_to[i]]=x, DFS(_to[i],x,d+1);
}
void Solve(int i)
{_Enum=0, memset(_H,0,sizeof _H);memset(vis,0,sizeof vis), memcpy(dgr,Dgr,sizeof dgr), Build(i);Max=0, DFS(i,i,1);int u=V;Max=0, DFS(u,u,1);if(Max>ans[0]){ans[ans[0]=Max]=V;while(V!=u) ans[--ans[0]]=V=pre[V];ans[0]=Max;}
}int main()
{
// freopen("guide.in","r",stdin);
// freopen("guide.out","w",stdout);srand(time(NULL));n=read(),m=read();for(int i=1; i<=m; ++i) AddEdge(read(),read());Dgr[0]=1000000;for(int T=10000; T; --T) Solve(rand()%n+1);//还是要多次
// for(int i=1; i<=n; ++i) Solve(i);printf("%d\n",ans[0]);for(int i=1; i<=ans[0]; ++i) printf("%d\n",ans[i]);return 0;
}
转载于:https://www.cnblogs.com/SovietPower/p/8981733.html
洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)相关推荐
- 洛谷 p4174 [noi2006] 最大获利 最小割(最大流),最大权闭合子图
题目 题解 题目 洛谷 p4174 建站花费p[i]元,如果a,b两个站都建起来了获利c元,问最大的获利. 题解 首先需要理解最大流求最大权闭合子图,这个我也不说了,又是转载博客. https://b ...
- 洛谷p2504 HAOI2006 聪明的猴子
[题目描述] 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着, 猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面的部分植物 ...
- [洛谷P4174][NOI2006]最大获利
题目大意:同Petya and Graph,数据范围改成$n\leqslant5\times10^3,m\leqslant5\times10^4$ 题解:同上 卡点:无 C++ Code: #incl ...
- 动态规划——洛谷_P1057传球游戏
题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...
- 洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game
洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game 题目描述 Bessie is playing a number game against Farmer John, ...
- 洛谷——P1056 排座椅
题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳. 同 ...
- 洛谷-DFS-1019-单词接龙-个人AC题解和公共AC题解笔记
学习内容: 预处理 万能头文件 string的使用 话不多说,直奔主题 本人AC代码 #include<iostream> #include<cstdio> #include& ...
- 洛谷找最小值c语言,洛谷 P1478 陶陶摘苹果(升级版) C语言实现
原题地址:P1478 淘淘摘苹果(升级版)- 洛谷 题目描述 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果,这次她有一个a公分的椅子.当他手够不着时,他会站到椅子上再试试. 这次与NO ...
- 深入理解 操作系统 LRU算法(以洛谷P1540题为例)
LRU算法 LeastRecentlyUsedLeast Recently UsedLeastRecentlyUsed 算法,意为"最近最少使用",这是操作系统内存管理部分重要的一 ...
最新文章
- Docker 概念详解
- pilt图像处理_Python用Pillow(PIL)进行简单的图像操作
- 【正一专栏】老夫老妻了,你还会说我爱你吗?
- 跟vczh看实例学编译原理——一:Tinymoe的设计哲学
- tensorflow怎样调用gpu_tensorflow基本用法(图,会话,tensor,变量等)
- Apache-Guacamole windows11 远程控制
- python主从_python—mariadb自动部署主从
- define 汉字 error C2001: newline in constant
- 转贴:电子商务如何提升网站转化率之:谷歌9条
- DataNode的流式接口
- 设计模式-17-迭代器
- 12、常见Conditional注解源码解析-ConditionalOnBean(写作中...)
- Leader:这样的 Bug 你也写的出来???
- 2015.4.7-C#入门基础(一)
- mysql 定时任务 日志_mysql定时备份任务
- python 埃米尔特_跨入第四维度–卡尔·埃米尔·卡尔森如何通过Unity创造艺术创作
- CAD2008 启动慢 卡住
- 添加打印机计算机无法访问,Win7系统添加打印机提示Windows无法打开“添加打印机”的解决方法...
- C语言牛顿迭代法求开平方
- 【neusoft】 Linux 的学习与使用
热门文章
- 数字vlsi芯片设计_【数字逻辑 | 数字逻辑导论】课程导论
- git 无法拉取项目,本地ping不通github的解决办法(详解)
- 【深度学习】图像特征提取与通道数问题(基于U型网络)
- 【Web安全】DVWA之Command injection(命令执行漏洞)探索
- 01背包【动态规划】
- cms php vue 开源_骑士CMS文件包含+getshell
- python 之属性_Python之对象的属性
- Warning: Instance created by `useForm` is not connect to any Form element. Forget to pass `form` pro
- 进阶学习(3.6) Prototype Pattern 原型模式
- 计算机笔记本电脑加固态硬盘,电脑卡的同学注意了 这些本加SSD也是渣