圖論 LeetCode面試題04.01 && 1334

面試題 04.01. 節點間通路

節點間通路。給定有向圖,設計一個算法,找出兩個節點之間是否存在一條路徑。

示例1:

 輸入:n = 3, graph = [[0, 1], [0, 2], [1, 2], [1, 2]], start = 0, target = 2
 輸出:true

示例2:

 輸入:n = 5, graph = [[0, 1], [0, 2], [0, 4], [0, 4], [0, 1], [1, 3], [1, 4], [1, 3], [2, 3], [3, 4]], start = 0, target = 4
 輸出 true

提示:

  1. 節點數量n在[0, 1e5]範圍內。
  2. 節點編號大於等於 0 小於 n。
  3. 圖中可能存在自環和平行邊。

 代碼:

思路:

圖使用鄰接表來表示

使用深度優先遍歷從節點start開始遍歷整張圖,使用visited數組存儲節點是否被訪問過。

如果target和start是存在一條路徑的,那麼visited[target]一定的true;

class Solution {
private:
	vector<vector<int> > g;//使用鄰接矩陣表示圖 
	vector<bool> visited;//是否被深搜過 
	void find(int start) 
	{
		visited[start] = true;
		//遍歷所有鄰邊
		for(int i=0; i<g[start].size(); i++)
		{
			if(!visited[g[start][i]])
            {
                find(g[start][i]);
            }
		} 
	}
public:
    bool findWhetherExistsPath(int n, vector<vector<int> >& graph, int start, int target) {
		//圖的構建 
		for(int i=0; i<n; i++)
			g.push_back(vector<int>());
		for(int i=0; i<graph.size(); i++)
		{	
			int v = graph[i][0];
			int w = graph[i][1];
			g[v].push_back(w);	
		}
		
		visited = vector<bool>(n,false); 
		find(start);
        return visited[target];
    }
};

1334. 閾值距離內鄰居最少的城市

有 n 個城市,按從 0 到 n-1 編號。給你一個邊數組 edges,其中 edges[i] = [fromi, toi, weighti] 代表 fromi 和 toi 兩個城市之間的雙向加權邊,距離閾值是一個整數 distanceThreshold

返回能通過某些路徑到達其他城市數目最少、且路徑距離 最大 爲 distanceThreshold 的城市。如果有多個這樣的城市,則返回編號最大的城市。

注意,連接城市 i 和 j 的路徑的距離等於沿該路徑的所有邊的權重之和。

示例 1:

輸入:n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
輸出:3
解釋:城市分佈圖如上。
每個城市閾值距離 distanceThreshold = 4 內的鄰居城市分別是:
城市 0 -> [城市 1, 城市 2] 
城市 1 -> [城市 0, 城市 2, 城市 3] 
城市 2 -> [城市 0, 城市 1, 城市 3] 
城市 3 -> [城市 1, 城市 2] 
城市 0 和 3 在閾值距離 4 以內都有 2 個鄰居城市,但是我們必須返回城市 3,因爲它的編號最大。

示例 2:

輸入:n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
輸出:0
解釋:城市分佈圖如上。 
每個城市閾值距離 distanceThreshold = 2 內的鄰居城市分別是:
城市 0 -> [城市 1] 
城市 1 -> [城市 0, 城市 4] 
城市 2 -> [城市 3, 城市 4] 
城市 3 -> [城市 2, 城市 4]
城市 4 -> [城市 1, 城市 2, 城市 3] 
城市 0 在閾值距離 4 以內只有 1 個鄰居城市。

這道題要注意一個示例

6
[[0,3,7],[2,4,1],[0,1,5],[2,3,10],[1,3,6],[1,2,1]]
417

輸出是5

 

思路:

使用鄰接表構建圖,注意,這邊是無向圖

使用Dijkstra算法計算各結點到其他結點最短路徑S<=distanceThreshold的個數

返回count值最小並且編號最大的那個節點

代碼:

struct node{
	int num;
	int weight;
	node(int num, int weight)
	{
		this->num=num;
		this->weight = weight;
	}
	bool operator < (const node& n) const
	{
		return weight>n.weight;
	}
};
class Solution {
private:
	vector<vector<node> > g;
	vector<int> count;//統計各結點到其他結點最短路徑S<=distanceThreshold的個數
	//使用Dijkstra算法計算各結點到其他結點最短路徑S<=distanceThreshold的個數 
	int Dijkstra(int start, int distanceThreshold)
	{
		vector<int> distTo(g.size(),-1);//存儲最短路徑 
		vector<bool> marked(g.size(),false);
		priority_queue<node> pq; 
		distTo[start] = 0;
		pq.push(node(start,0));
		while(!pq.empty())
		{
			node v = pq.top();
			pq.pop();
			if(marked[v.num])
				continue;
			marked[v.num]=true;
			//遍歷所有鄰邊
			for(int i=0; i<g[v.num].size(); i++)
			{
				node w = g[v.num][i];
                if(!marked[w.num])
                {
                    if(distTo[w.num]==-1 || distTo[v.num]+w.weight<distTo[w.num])
				    {
					    distTo[w.num] = distTo[v.num]+w.weight;
					    pq.push(node(w.num,distTo[w.num]));
				    }
                }
				
			} 
		}
		int count =0; 
		for(int i=0; i<distTo.size(); i++)
		{
			if(distTo[i] >0 && distTo[i] <= distanceThreshold)
				count++;
		}
		return count;
	} 
public:
    int findTheCity(int n, vector<vector<int> >& edges, int distanceThreshold) {
    	count = vector<int>(n,0);
		for(int i=0; i<n; i++)
			g.push_back(vector<node>());
		//使用鄰接表表示圖
		for(int i=0; i<edges.size(); i++)
		{
			//無向邊 
			int from = edges[i][0];
			int to = edges[i][1];
			int weight = edges[i][2];
			node node1(to,weight);
			g[from].push_back(node1);
			node node2(from,weight);
			g[to].push_back(node2);
			
		} 
        int res = 0;
		for(int i=0; i<n; i++)
		{
			count[i] = Dijkstra(i,distanceThreshold);
		}
		int minCount=-1;
		for(int i=0; i<n; i++)
		{
			if(minCount==-1 && count[i]!= 0)
			{
				minCount = count[i];
				res = i;
			}
			else{
				if(count[i]<=minCount && count[i]!= 0)
				{
					minCount = count[i];
					res = i;
				}
			}
		}
		return res;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章