点此看题面

大致题意: 给你一张\(n\)个点、\(m\)条边的无向图,让你找出图上的一条不经过重复节点的最长路(提答+\(spj\))。

随机化乱搞

针对这种提答题,我们就要用随机化乱搞(Cptraser大佬说他可以直接\(O(n^2)\)求出答案%%% )。

首先,我们随机一个节点作为起点

然后,我们从这个节点出发,每次选择一个还没有访问过度数较小(这可以通过随机化实现) 的相邻节点进行遍历。

遍历完该节点之后,如果还有没有访问过的相邻节点,就重复上述操作。

呃,貌似就这么简单?

当然,随机化算法肯定要循环操作若干次,推荐\(5000\)次(毕竟它是提答,就算\(5000\)次没\(rand\)出答案,还可以继续\(rand\))。

有一个细节需要注意:选择一个点之后,要将与这个节点相邻的节点的度数减1。(我就是因为没这样做\(rand\)了整整一个晚上都没\(rand\)出正确答案,加上这个细节之后秒出答案)

具体实现还是看代码吧。

代码

#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e9
#define Inc(x,y) ((x+=(y))>=MOD&&(x-=MOD))
#define ten(x) (((x)<<3)+((x)<<1))
#define N 10000
#define add(x,y) (e[++ee].nxt=lnk[x],++deg[e[lnk[x]=ee].to=y])
#define hl_AK_NOI true
using namespace std;
int n,m,ee=0,lnk[N+5],deg[N+5];
struct edge
{
int to,nxt;
}e[2*N+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
int f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];
public:
FIO() {FinNow=FinEnd=Fin;}
inline void read(int &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=ten(x)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void read_char(char &x) {while(isspace(x=tc()));}
inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc())) if(!~ch) return;}
inline void write(int x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {register int i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
inline void end() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class Class_RandSolver//听起来很高大上的名字,实际上就是随机化
{
private:
int vis[N+5];
struct Status
{
int ans,rt,lst[N+5],dis[N+5];//ans记录最长路径长度,rt记录起点,lst数组记录每个节点的上一个节点(方便输出路径),dis记录起点到达每一个节点的距离
inline void Clear() {ans=0,memset(lst,0,sizeof(lst)),memset(dis,0,sizeof(dis));}//清空
}NowAns,MaxAns;//NowAns记录当前答案,MaxAns记录最优答案
inline void Clear() {NowAns.Clear(),memset(vis,0,sizeof(vis));}//清空
inline void dfs(int x)//搜索
{
register int i,t,flag;vis[x]=1;//标记已访问
if(NowAns.dis[x]>NowAns.ans) NowAns.ans=NowAns.dis[x];//更新最长路径长度
for(i=lnk[x];i;i=e[i].nxt) --deg[e[i].to];//将与当前节点相邻的节点度数减1
while(hl_AK_NOI)//怀着崇高的信仰膜拜hl,这样就可以++RP
{
for(t=flag=0,i=lnk[x];i;i=e[i].nxt) if(!vis[e[i].to]) flag=1,deg[e[i].to]<deg[t]&&1.0*n/deg[e[i].to]*rand()>=RAND_MAX&&(t=e[i].to);//选择一个没被访问过的度数较小的相邻节点,注意加上一些随机化的因素
if(!flag) break;//如果没有没被访问过的相邻节点,就退出循环
if(!t) continue;//如果刚才没有找到节点,就重新找一遍
NowAns.dis[t]=NowAns.dis[x]+1,NowAns.lst[t]=x,dfs(t);//对这个相邻节点进行dfs
}
for(i=lnk[x];i;i=e[i].nxt) ++deg[e[i].to];//将刚才减掉的度数加回去
}
public:
Class_RandSolver() {srand(time(NULL)),srand(rand()),srand(rand());}//初始化
inline void GetAns()//求解答案
{
Clear(),NowAns.dis[NowAns.rt=rand()%n+1]=1,dfs(NowAns.rt);//随机一个起点开始dfs
if(NowAns.ans>MaxAns.ans) MaxAns=NowAns;//如果得到的答案比最优答案大,更新最优答案
}
inline void PrintAns()//输出答案
{
register int i;
for(F.write(MaxAns.ans),F.write_char('\n'),i=1;i<=n;++i) if(MaxAns.dis[i]==MaxAns.ans) break;//找到一个终点
while(i^MaxAns.rt) F.write(i),F.write_char('\n'),i=MaxAns.lst[i];F.write(MaxAns.rt);//输出路径
}
}RandSolver;
int main()
{
register int i,x,y,ans=0;
for(F.read(n),F.read(m),i=1;i<=m;++i) F.read(x),F.read(y),add(x,y),add(y,x);
for(deg[0]=INF,i=1;i<=5000;++i) RandSolver.GetAns();//循环5000次求出答案
return RandSolver.PrintAns(),F.end(),0;
}

【洛谷4252】[NOI2006] 聪明的导游(提答题)的更多相关文章

  1. 洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)

    题目链接 随机化 暴力: 随便从一个点开始DFS,每次从之前得到的f[i]最大的子节点开始DFS.f[i]为从i开始(之前)能得到的最大答案. 要注意的是f[i]应当有机会从更小的答案更新, 9.10 ...

  2. 洛谷 P2504 [HAOI2006]聪明的猴子

    洛谷 P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水 ...

  3. 洛谷 P4397 [JLOI2014]聪明的燕姿 / TOPOI 测验1315, 问题E: 1935: 聪明的燕姿 解题报告

    题目链接 : 1. 洛谷 2.topoi . 大致题意:输入一个数s,找出所有约数和为s的数 关于一个数的约数和求法: 一个>1的整数可以被分解为多个 质数 的乘方,设数 s = p1k1 *  ...

  4. 洛谷 P4174 [NOI2006]最大获利 解题报告

    P4174 [NOI2006]最大获利 题目描述 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU 集团旗下的 CS&T 通讯公司在新一代通讯技术血战的前夜,需要 ...

  5. 洛谷 P4297 [NOI2006]网络收费

    P4297 [NOI2006]网络收费 题目背景 noi2006 day1t1 题目描述 网络已经成为当今世界不可或缺的一部分.每天都有数以亿计的人使用网络进行学习.科研.娱乐等活动.然而,不可忽视的 ...

  6. 洛谷—— P2504 [HAOI2006]聪明的猴子

    P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上. ...

  7. 洛谷——P2504 [HAOI2006]聪明的猴子

    P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上. ...

  8. 【洛谷p1314】聪明的质监员

    聪明的质监员[题目链接] 有关算法: 二分答案: 但是你只二分答案是不够的,因为你check会炸,所以还要考虑前缀和: 首先假装我们的check已经写好了,main函数: int main() { n ...

  9. 洛谷P4204 [NOI2006]神奇口袋 数论

    正解:数论 解题报告: 传送门 第一次用\(\LaTeX\)和\(markdown\),,,如果出了什么锅麻烦在评论跟我港句QAQ \(1)x_{i}\)可以直接离散 \(2)y_{i}\)的顺序对结 ...

随机推荐

  1. luogu1975 排队(分块)

    luogu1975 排队(分块) 给你一个长度为n的序列,每次交换给定的两个数,输出每次操作后的逆序对个数. 首先考虑求出刚开始的逆序对.接着相当于带修改的求区间中比x大的数. 可以用分块,每个块内排 ...

  2. 洛谷P2474 [SCOI2008]天平

    P2474 [SCOI2008]天平 题目背景 2008四川NOI省选 题目描述 你有n个砝码,均为1克,2克或者3克.你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系.你把其中两个砝码A ...

  3. MCP|LQ|DIAlignR provides precise retention time alignment across distant runs in DIA and targeted proteomics

    文献名: DIAlignR provides precise retention time alignment across distant runs in DIA and targeted prot ...

  4. centos7 yum快速安装php7.1

    1. 安装nginx yum install nginx ##开启nginx service nginx start 2.安装MYSQLyum localinstall http://dev.mysq ...

  5. State模式(状态设计模式)

    State??? State模式中,我们用类来表示状态.以类来表示状态后,我们就能通过切换类来方便地改变对象的状态.当需要增加新的状态时,如何修改代码这个问题也会很明确. 直接用状态代替硬编码 依赖于 ...

  6. PHPExcel探索之旅---阶段三 绘制图表

    利用PHPExcel插件进行绘制图表 <?php /** * 使用PHPExcel插件在excel文件中利用其中的数据建立折线图 * */ $dir = dirname(__FILE__); r ...

  7. Luogu P2480 [SDOI2010]古代猪文 卢卡斯+组合+CRT

    好吧刚开始以为扩展卢卡斯然后就往上套..结果奇奇怪怪又WA又T...后来才意识到它的因子都是质数...qwq怕不是这就是学知识学傻了.. 题意:$ G^{\Sigma_{d|n} \space C_n ...

  8. devtools实现springboot的热部署

    spring-boot-devtools介绍: spring-boot-devtools 是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去.原理是在发现代码有更改 ...

  9. Fence Repair (二叉树求解)(优先队列,先取出小的)

    题目链接:http://poj.org/problem?id=3253 Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Sub ...

  10. windows 7 elasticsearch-5.3.2

    # windows elasticsearch- D:\nescafe\elasticsearch-\bin λ java -version java version "1.8.0_121& ...