1. 程式人生 > 其它 >leetcode310. 最小高度樹(bfs,拓撲)

leetcode310. 最小高度樹(bfs,拓撲)

連結:https://leetcode-cn.com/problems/minimum-height-trees/

思路:
取最小高度的樹即為,取路徑最長的路線的中點最為樹根,因此當最長路徑長度為2的倍數時會存在兩個解
因為是無向圖,所以葉子節點的入度為1,我們可以將所以葉子節點入隊,當剩餘的節點小於等於2時,即剩下節點為答案
迴圈葉子節點入隊 ,所指向的節點如果入度大於1,入度減一;

vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
	if (n == 1)
		return { 0 };
	else if (n == 2)
		return{ 0,1 };

	vector<int> indegree(n,0);//入度陣列,並初始化
	vector<int> v;
	vector<vector<int>> graph(n,v);//圖形表示,並初始化
	for (int i = 0; i < edges.size(); i++)//構造圖與入度陣列:無向圖,兩個點都要處理
	{
		graph[edges[i][0]].push_back(edges[i][1]);
		graph[edges[i][1]].push_back(edges[i][0]);
		indegree[edges[i][0]]++;
		indegree[edges[i][1]]++;
	}
	queue<int> myqueue;//裝載入度為1的queue
	for (int i = 0; i < n; i++)
	{
		if (indegree[i] == 1)
			myqueue.push(i);
	}
	int cnt = myqueue.size();//!!令cnt等於myqueue.size(),一次性將入度為1的點全部刪去。
	while (n>2)
	{
		n -= cnt;//一次性將入度為一的點全部刪去!!不能一個一個刪!
		while (cnt--)
		{
			int temp = myqueue.front();
			myqueue.pop();
			indegree[temp] = 0;
			//更新temp的鄰接點:若temp臨接點的入度為1,則將其放入queue中。
			for (int i = 0; i < graph[temp].size(); i++)
			{
				if (indegree[graph[temp][i]] != 0)
				{
					indegree[graph[temp][i]]--;
					if (indegree[graph[temp][i]] == 1)//放在這裡做!只判斷鄰接點。
						myqueue.push(graph[temp][i]);
				}
				
			}
		}
		cnt = myqueue.size();
	}
	vector<int> result;
	while (!myqueue.empty())
	{
		result.push_back(myqueue.front());
		myqueue.pop();
	}
	return result;
}
};