【FOJ2207 11月月赛C】【DFS栈性质应用 离线处理】以撒的结合 从x到y路径上的第k个点 询问众多

本文主要是介绍【FOJ2207 11月月赛C】【DFS栈性质应用 离线处理】以撒的结合 从x到y路径上的第k个点 询问众多,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 Problem 2207 以撒的结合

Accept: 30    Submit: 98
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

小茗同学最近在认真地准备比赛,所以经常玩以撒的结合。

《以撒的结合》是一款由Edmund McMillen,Florian Himsl 开发,并由Edmund McMillen最早于2011年09月29日发行的一款2D平面角色扮演、动作冒险类的独立游戏。游戏的角色将在有着能够提升能力的道具与特殊技能的半RPG世界中闯荡。

——来自百度百科

小茗同学在打BOSS前,费掉了很多HP。在地图的一些房间里有补充HP的红心,然而小茗同学受到了看不见地图的诅咒。凭借不知道哪里来的记忆,小茗同学记得某个有红心的房间在房间A与房间B的路上的第K个房间里。为了简化问题,我们把地图看成一棵树。小茗同学想知道A到B的第K个房间号为多少,由于小茗同学很累,所以现在这个任务交给你了。

 Input

第一行是一个整数T(T<=10),表示有T组测试数据。

每组数据的第一行为两个整数n m(0<n<=1000,0<m<=n*n),分别表示房间个数和询问次数。

接下来n-1行,每行两个整数u v(0<u、v<=n,且u≠v),表示地图上房间u和房间v有一条路径。

最后是m行,每行三个整数u v k,表示询问房间u到房间v的路径上的第k个房间。

输入数据保证合法,即k不超过u、v的最短距离。

 Output

对于每组数据,首先第一行先输出“Case #x:“ ,其中x是从1开始,表示数据组号,接下来m行,每行输出相应的房间号。

 Sample Input

16 31 22 42 51 33 64 6 41 6 24 5 3

 Sample Output

Case #1:335

 Source

FOJ有奖月赛-2015年11月



【FOJ2207 11月月赛C】【DFS栈性质应用 离线处理】以撒的结合 从x到y路径上的第k个点 询问众多 DFS AC

#include<stdio.h> 
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=1010,M=0,Z=1e9+7,ms63=1061109567;
int casenum,casei;
int n,m,x,y,k;
int st,top,tim;
vector<int>a[N];
int first[N][N];int id;
struct query
{int k,o,nxt;
}q[N*N];
int e[N],s[N],ans[N*N];
void dfs(int x)
{e[x]=tim;s[++top]=x;for(int z=first[st][x];z;z=q[z].nxt){int k=q[z].k;int o=q[z].o;ans[o]=s[k];}first[st][x]=0;for(int i=a[x].size()-1;~i;--i){int y=a[x][i];if(e[y]!=tim)dfs(y);}--top;
}
int main()
{scanf("%d",&casenum);for(casei=1;casei<=casenum;casei++){scanf("%d%d",&n,&m);if(n>1000||m>n*n)return 0;for(int i=1;i<=n;i++)a[i].clear();for(int i=1;i<n;i++){scanf("%d%d",&x,&y);a[x].push_back(y);a[y].push_back(x);}id=0;for(int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&k);++id;q[id].k=k;q[id].o=i;q[id].nxt=first[x][y];first[x][y]=id;}for(st=1;st<=n;st++){++tim;dfs(st);}printf("Case #%d:\n",casei);for(int i=1;i<=m;i++)printf("%d\n",ans[i]);}return 0;
}
/*
【trick&&吐槽】
1,不看数据规模就做真的是好蠢好蠢,数据规模也是对做法的提示。
2,dfs上有很多精妙的性质和应用。
3,lca问题我竟然忘记了要把双向边都放进去+_+,然而竟然能过样例,天哪【题意】
给你一棵树,树上有n(1e3)个点。
我们有m个询问,m最大为n*n。
对于每个询问,给你(x,y,k),问你从x到y上的第k个房间的是多少。【类型】
LCA or 树链剖分?NO!正解是栈性质dfs!【分析】
这题我一看到是树结构,立马想到树链剖分或者是LCA这样O(mlogn)的做法。
然而m实在是太大了,这个做法只会造成TLE >_<
正解是怎么做呢?DFS!
我们用vector存下所有询问(x,y,k)
[哇哇哇,vector太大也会导致TLE!换成链表模式就AC了>_<]
然后从每个点开始dfs,用栈存下所有点。
如果遇到(x,y,k)的询问,我们就直接记录答案为目前从x开始dfs的栈中第k个点。
这样就可以AC喽~【时间复杂度&&优化】
O(n^2)*/

【FOJ2207 11月月赛C】【DFS栈性质应用 离线处理】以撒的结合 从x到y路径上的第k个点 询问众多 LCA TLE

#include<stdio.h> 
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=1010,M=0,Z=1e9+7,ms63=1061109567;
int casenum,casei;
int n,m,x,y,k;
vector<int>a[N];
int d[N];
int f[N][12];
int b[12];
void dfs(int x)
{for(int i=a[x].size()-1;~i;--i){int y=a[x][i];if(y==f[x][0])continue;f[y][0]=x;d[y]=d[x]+1;dfs(y);}
}
void LCAinit()
{for(int j=1;b[j]<n;j++){for(int i=1;i<=n;i++)if(~f[i][j-1]){f[i][j]=f[f[i][j-1]][j-1];}}
}
int DX,DY;
int LCA(int x,int y)
{int i,j;if(d[x]<d[y])swap(x,y);for(i=0;b[i]<=d[x];i++);i--;for(j=i;d[x]>d[y];j--)if(d[x]-b[j]>=d[y])x=f[x][j];if(x==y)return x;for(j=i;f[x][0]!=f[y][0];j--)if(f[x][j]!=f[y][j]){x=f[x][j];y=f[y][j];}return f[x][0];
}
int find(int x,int dis)
{int i;for(i=0;b[i]<=dis;i++);i--;while(dis){if(dis>=b[i]){x=f[x][i];dis-=b[i];}}return x;
}
int main()
{for(int i=0;i<=10;i++)b[i]=1<<i;scanf("%d",&casenum);for(casei=1;casei<=casenum;casei++){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)a[i].clear();for(int i=1;i<n;i++){scanf("%d%d",&x,&y);a[x].push_back(y);a[y].push_back(x);}MS(f,-1);f[1][0]=0;d[1]=0;dfs(1);LCAinit();printf("Case #%d:\n",casei);while(m--){scanf("%d%d%d",&x,&y,&k);k--;int lca=LCA(x,y);int dx=d[x]-d[lca];int dy=d[y]-d[lca];int ans;if(dx>=k)ans=find(x,k);else{k-=dx;ans=find(y,dy-k);}printf("%d\n",ans);}}return 0;
}
/*
【trick&&吐槽】
1,不看数据规模就做真的是好蠢好蠢,数据规模也是对做法的提示。
2,dfs上有很多精妙的性质和应用。
3,lca问题我竟然忘记了要把双向边都放进去+_+,然而竟然能过样例,天哪【题意】
给你一棵树,树上有n(1e3)个点。
我们有m个询问,m最大为n*n。
对于每个询问,给你(x,y,k),问你从x到y上的第k个房间的是多少。【类型】
LCA or 树链剖分?NO!正解是栈性质dfs!【分析】
这题我一看到是树结构,立马想到树链剖分或者是LCA这样O(mlogn)的做法。
然而m实在是太大了,这个做法只会造成TLE >_<
正解是怎么做呢?DFS!
我们用vector存下所有询问(x,y,k)
[哇哇哇,vector太大也会导致TLE!换成链表模式就AC了>_<]
然后从每个点开始dfs,用栈存下所有点。
如果遇到(x,y,k)的询问,我们就直接记录答案为目前从x开始dfs的栈中第k个点。
这样就可以AC喽~【时间复杂度&&优化】
O(n^2)*/


这篇关于【FOJ2207 11月月赛C】【DFS栈性质应用 离线处理】以撒的结合 从x到y路径上的第k个点 询问众多的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/610501

相关文章

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

Redis如何使用zset处理排行榜和计数问题

《Redis如何使用zset处理排行榜和计数问题》Redis的ZSET数据结构非常适合处理排行榜和计数问题,它可以在高并发的点赞业务中高效地管理点赞的排名,并且由于ZSET的排序特性,可以轻松实现根据... 目录Redis使用zset处理排行榜和计数业务逻辑ZSET 数据结构优化高并发的点赞操作ZSET 结

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约