神秘国度的爱情故事
题目要求:某个太空神秘国度中有很多美丽的小村,从太空中可以想见,小村间有路相连,更精确一点说,任意两村之间有且仅有一条路径。小村 A 中有位年轻人爱上了自己村里的美丽姑娘。每天早晨,姑娘都会去小村 B 里的面包房工作,傍晚 6 点回到家。年轻人终于决定要向姑娘表白,他打算在小村 C 等着姑娘路过的时候把爱慕说出来。问题是,他不能确定小村 B 是否在小村 A到小村 C 之间的路径上。你可以帮他解决这个问题吗?
输入 :第一行是村庄的个数M,接下来M-1行每行两个树Va,Vb表示哪些村庄是直接相连的,之后是提问次数N,接下来N行每行3个整数va,vb,vc,每组发问若vb在va与vc的必经之路上则输出"yes",否则输出"No"
设计思想
有两个类:Create_Sample //产生样本的类,
Yes_or_NO //判对是否告白成功的类
类里面的函数,成员,和功能,都在上面的图中说明了.
下面就来说说算法设计原理:
①首先通过Create_Sample来产生测试数据,如何产生随机,不重复的,n个数呢.
思路:产生一个n大小的升序数组, 对数据中任意u,v来个数交换即可.保存在queue中
②如何产生随机,不重复的n-1条边呢.
思路:利用两个queue,来配合交互,产生,具体可看代码实现
③如何产生随机,m次正确有效询问呢.
思路:不予许错误的提问即可,如代码中,当a == b || b == c || a == c,这些无意义的提问,直接不允许就行,具体实现看代码
④接着有了数据就开始Yes_or_No了
首先,通过构造函数,来动态申请空间
接着,将边集连起来,形成一个无向图
接着,用bfs广度优先搜索预处理一下这个图,为图中的点之间形成父子关系,和深度关系,用于下一步.
(具体的父子关系,和深度关系怎么预处理请看具体代码实现,这里不加赘述)
接着,用LCA最近公关祖先算法,找到两点之间的最近公共祖先,这里用到了预处理的父子关系,和深度关系的方法来找祖先.
最后,用meeeeet函数来判断,a,b,c的点lca关系,从而得到小伙子是否可以遇见姑娘.
最后的最后,析构函数,释放空间
源程序
#include <bits/stdc++.h>
using namespace std;
int top = 1;
char test[] = "test2222.txt";
char out[] = "out2222.txt";
class Create_Sample //产生样本的类
{
private:
queue<int> q;
queue<int> que;
public:
void init(int n); //产生一组1-n不重复的数
void creattree(int n);
void creatquery(int n);
};
class Yes_or_NO //判对是否告白成功的类
{
private:
struct Edge_node
{
int adjnode;
Edge_node *next;
};
struct Node
{
int id;
int fa;
int depth;
Edge_node *fristarc;
};
public:
Node *node;
Yes_or_NO(int n)
{
node = new Node[n + 1]; //动态申请n+1个结点空间
};
void cr