U504405 破译诸葛亮的密码箱

重新写了一遍更详细:

代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
struct Node{
	int data;//存节点数据
	Node *next;//结构体类型的指针 
};
const int N = 1e5+5;
int T;//T组数据
int n;//n个节点 
int a,b;//两点 
int x,y;//两点构成的边 
Node *list[N]; 
vector <int> Path;
bool vis_Path[N];//标记路径函数 
bool vis_longest[N];//标记最远函数 
int distant = 0;//最远距离 
int ans[N];//记录答案 
void init()
{

	memset(list,0,sizeof(list));
	memset(vis_longest,false,sizeof(vis_longest));
	memset(vis_Path,false,sizeof(vis_Path));
	Path.clear();//清空路径数组
	distant = -1e6;
}
void check(bool found)
{
		if(found) // 查找从a到b的路径
		{
            cout << "Path from " << a << " to " << b << ": ";
            for (int node : Path) 
			{
                cout << node << " ";
            }
            cout << endl;
        }
		else 
		{
            cout << "No path found from " << a << " to " << b << endl;
        }
        
}
void addNode(int scr,int dest)//创建无向图的函数 
{
	//无向图 
	Node *newNode1 = (Node*)malloc(sizeof(Node));
	newNode1->data = dest;
	newNode1->next = list[scr];
	list[scr] = newNode1;
	
	Node *newNode2 = (Node*)malloc(sizeof(Node));
	newNode2->data = scr;
	newNode2->next = list[dest];
	list[dest] = newNode2;
}
bool node_path(int current,int target)
{
	vis_Path[current] = true; 
	Path.push_back(current);//加入元素 
	if(current == target)
	{
		return true;
	} 
	Node *temp = list[current];//创建一个指针指向当前节点 
	while(temp) 
	{
		int adjpos = temp->data;//当前节点相邻节点的下标 
		if(vis_Path[adjpos] == false)
		{
			bool result = node_path(adjpos,target);
			if(result)
			return true;
		}
	 	temp = temp->next;//下一个相邻节点 
	}
	Path.pop_back();//移除最近加入的元素  
	return false; 
}
void longest(int current,int step) 
{
	if(step > distant)
	{
		distant = step;	
	}
	
	Node *temp = list[current];
	while(temp)
	{
		int adjpos = temp->data;
		if(vis_longest[adjpos] == false)
		{
			vis_longest[adjpos] = true;
			longest(adjpos,step+1);
		}
		temp = temp->next;//指向下一个相邻节点 	
	} 
 } 
int main() 
{
	cin >> T;
	for(int t = 1 ; t <= T ; t++)
	{
		init();
		cin >> n;
		cin >> a >> b;
		for(int i = 1 ; i <= n-1 ; i++)//n-1条边 
		{
			cin >> x >> y;
			addNode(x,y);
		}
		bool F = node_path(a,b);
//		check(F); 
		int len = Path.size();
		int meeting = Path[(len-1)/2] ;//以b为基准触碰到红色格子作为相遇点的下标 
//		cout << "下标:" << meeting <<endl; 
//		cout << "len:" << len <<endl; 
		vis_longest[meeting] = true;
		longest(meeting,0);//记算相遇点走到最远节点的距离
//		cout << "distant:" << distant<< endl; 
		ans[t] = (n-1)*2-distant+len/2; 
	} 
	for(int i = 1 ; i <= T ; i++)
	cout << ans[i] << endl; 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值