题目链接

随机化 暴力:
随便从一个点开始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]聪明的导游(提答 直径 随机化)相关推荐

  1. 洛谷 p4174 [noi2006] 最大获利 最小割(最大流),最大权闭合子图

    题目 题解 题目 洛谷 p4174 建站花费p[i]元,如果a,b两个站都建起来了获利c元,问最大的获利. 题解 首先需要理解最大流求最大权闭合子图,这个我也不说了,又是转载博客. https://b ...

  2. 洛谷p2504 HAOI2006 聪明的猴子

    [题目描述] 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着, 猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面的部分植物 ...

  3. [洛谷P4174][NOI2006]最大获利

    题目大意:同Petya and Graph,数据范围改成$n\leqslant5\times10^3,m\leqslant5\times10^4$ 题解:同上 卡点:无 C++ Code: #incl ...

  4. 动态规划——洛谷_P1057传球游戏

    题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...

  5. 洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game

    洛谷 2953  [USACO09OPEN]牛的数字游戏Cow Digit Game 题目描述 Bessie is playing a number game against Farmer John, ...

  6. 洛谷——P1056 排座椅

    题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳. 同 ...

  7. 洛谷-DFS-1019-单词接龙-个人AC题解和公共AC题解笔记

    学习内容: 预处理 万能头文件 string的使用 话不多说,直奔主题 本人AC代码 #include<iostream> #include<cstdio> #include& ...

  8. 洛谷找最小值c语言,洛谷 P1478 陶陶摘苹果(升级版) C语言实现

    原题地址:P1478 淘淘摘苹果(升级版)- 洛谷 题目描述 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果,这次她有一个a公分的椅子.当他手够不着时,他会站到椅子上再试试. 这次与NO ...

  9. 深入理解 操作系统 LRU算法(以洛谷P1540题为例)

    LRU算法 LeastRecentlyUsedLeast Recently UsedLeastRecentlyUsed 算法,意为"最近最少使用",这是操作系统内存管理部分重要的一 ...

最新文章

  1. Docker 概念详解
  2. pilt图像处理_Python用Pillow(PIL)进行简单的图像操作
  3. 【正一专栏】老夫老妻了,你还会说我爱你吗?
  4. 跟vczh看实例学编译原理——一:Tinymoe的设计哲学
  5. tensorflow怎样调用gpu_tensorflow基本用法(图,会话,tensor,变量等)
  6. Apache-Guacamole windows11 远程控制
  7. python主从_python—mariadb自动部署主从
  8. define 汉字 error C2001: newline in constant
  9. 转贴:电子商务如何提升网站转化率之:谷歌9条
  10. DataNode的流式接口
  11. 设计模式-17-迭代器
  12. 12、常见Conditional注解源码解析-ConditionalOnBean(写作中...)
  13. Leader:这样的 Bug 你也写的出来???
  14. 2015.4.7-C#入门基础(一)
  15. mysql 定时任务 日志_mysql定时备份任务
  16. python 埃米尔特_跨入第四维度–卡尔·埃米尔·卡尔森如何通过Unity创造艺术创作
  17. CAD2008 启动慢 卡住
  18. 添加打印机计算机无法访问,Win7系统添加打印机提示Windows无法打开“添加打印机”的解决方法...
  19. C语言牛顿迭代法求开平方
  20. 【neusoft】 Linux 的学习与使用

热门文章

  1. 数字vlsi芯片设计_【数字逻辑 | 数字逻辑导论】课程导论
  2. git 无法拉取项目,本地ping不通github的解决办法(详解)
  3. 【深度学习】图像特征提取与通道数问题(基于U型网络)
  4. 【Web安全】DVWA之Command injection(命令执行漏洞)探索
  5. 01背包【动态规划】
  6. cms php vue 开源_骑士CMS文件包含+getshell
  7. python 之属性_Python之对象的属性
  8. Warning: Instance created by `useForm` is not connect to any Form element. Forget to pass `form` pro
  9. 进阶学习(3.6) Prototype Pattern 原型模式
  10. 计算机笔记本电脑加固态硬盘,电脑卡的同学注意了 这些本加SSD也是渣