面試題 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
提示:
- 節點數量n在[0, 1e5]範圍內。
- 節點編號大於等於 0 小於 n。
- 圖中可能存在自環和平行邊。
代碼:
思路:
圖使用鄰接表來表示
使用深度優先遍歷從節點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;
}
};