HDU_2586_How far away ?_MLE_tarjan

#include<iostream>      
#include<sstream>      
#include<string>      
#include<vector>      
#include<list>      
#include<set>      
#include<map>      
#include<stack>      
#include<queue>      
#include<algorithm>      
#include<cmath>      
#pragma warning(disable:4996)      
using std::cin;
using std::cout;
using std::endl;
using std::stringstream;
using std::string;
using std::vector;
using std::list;
using std::pair;
using std::set;
using std::multiset;
using std::map;
using std::multimap;
using std::stack;
using std::queue;
class DisjoinSet
{
public:
	vector<int>represent, rank;
	DisjoinSet(const int &n) :represent(n), rank(n)
	{
		for (int i = 0; i < n; i++)
		{
			represent[i] = i;
		}
	}
	int find(int i)
	{
		return represent[i] = represent[i] == i ? i : find(represent[i]);
	}
	void merge(const int &x, const int &y)
	{
		auto a = find(x); auto b = find(y);
		if (rank[a] < rank[b])
		{
			represent[a] = b;
		}
		else
		{
			represent[b] = a;
			if (rank[b] == rank[a])
			{
				rank[a]++;
			}
		}
	}
};
class Tree
{
public:
	int vertex;//树中的结点数
	int edge;//树中的边树
	vector<vector<pair<int,int>>>adjList;//邻接表,pair.first=destination vertex;pair.second=weight
	map<pair<int, int>, pair<int, int>>lca;//结点first和second的最近公共祖先以及first到second的最短距离
	Tree()
	{
		vertex = edge = 0;
	}
	Tree(const int &v,const int &e)
	{
		vertex = v;
		edge = e;
		adjList.resize(v + 1);
	}
	//当前遍历到的结点以及其到根的距离
	void LRN_sub(vector<bool>&visited,DisjoinSet &union_set,int curvertex)
	{
		visited[curvertex] = true;
		for (size_t i = 0; i < adjList[curvertex].size(); i++)
		{
			if (!visited[adjList[curvertex][i].first])
			{
				
				LRN_sub(visited, union_set, adjList[curvertex][i].first);
				//子树的祖先为其父母
				union_set.represent[adjList[curvertex][i].first] = curvertex;
			}
		}
		for (int i = 1; i <= vertex; i++)
		{
			if (visited[i])
			{
				lca.insert({ {std::min(curvertex,i),std::max(curvertex,i) },{union_set.find(i),0} });
			}
		}
	}
	void dfs(vector<int>&distance,int curvertex)
	{
		for (size_t i = 0; i < adjList[curvertex].size(); i++)
		{
			distance[adjList[curvertex][i].first] = distance[i]+ adjList[curvertex][i].second;
			dfs(distance, adjList[curvertex][i].first);
		}
	}
	void LRN_main()
	{
		vector<bool>visited(vertex+1);//结点是否被访问过
		DisjoinSet union_set(vertex + 1);
		LRN_sub(visited,  union_set, 1);
		vector<int>distance(vertex + 1);//结点到根的距离
		dfs(distance, 1);
		for (int i = 1; i <= vertex; i++)
		{
			for (int j = i+1; j <= vertex; j++)
			{
				map<pair<int, int>, pair<int, int>>::iterator iter = lca.find({i,j});
				iter->second.second = distance[iter->first.first] + distance[iter->first.second] - 2 * distance[iter->second.first];
			}
		}
	}
};
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int T; cin >> T;
	while (T--)
	{
		int vertex, query;
		cin >> vertex >> query;
		Tree tree(vertex,vertex-1);
		for (int i = 0; i < vertex-1; i++)
		{
			int first, second, weight;
			cin >> first >> second >> weight;
			tree.adjList[std::min(first, second)].push_back({ std::max(first,second),weight });
		}
		tree.LRN_main();
		for (int i = 0; i < query; i++)
		{
			int first, second;
			cin >> first >> second;
			map<pair<int, int>, pair<int, int>>::iterator iter = tree.lca.find({ std::min(first,second),std::max(first,second) });
			cout << iter->second.second << endl;
		}
	}
	return 0;
}

你可能感兴趣的:(HDU,LCA)