简体   繁体   English

有向图中的DFS和字典路径?

[英]DFS and lexicographic path in directed graph?

  • Given directed graph have N(1<=N<=10^5) vertices and M(1<=M<=10^6) edges, no loop-self.给定的有向图有 N(1<=N<=10^5) 个顶点和 M(1<=M<=10^6) 个边,没有自循环。 Given source vertex s and destination vertex t.给定源顶点 s 和目标顶点 t。 Print lexicographical smallest path from s to t (Note: All nodes in this path are distinguish)打印从 s 到 t 的字典最小路径(注意:该路径中的所有节点都是区分的)

For example: We have N=4 and M=4 and E={{1,4},{4,2},{1,2},{2,3}}, s=1 and t=3.例如:我们有 N=4 和 M=4 和 E={{1,4},{4,2},{1,2},{2,3}},s=1 和 t=3。 So the answer is 1->2->3.所以答案是 1->2->3。

This is my attemp: I used DFS-Algorithm to list all path from s to t.这是我的尝试:我使用 DFS 算法列出了从 s 到 t 的所有路径。 And add them into vector<vector>.并将它们添加到 vector<vector> 中。 Then, I sort it and print the first path.然后,我对其进行排序并打印第一条路径。 But I got TLE.但我得到了 TLE。

Now, I don't know how to optimize this problem, can you help me this stuck现在,我不知道如何优化这个问题,你能帮我解决这个问题吗

This is my code这是我的代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn (ll)(1e5+5)
#define pb push_back
vector<ll> adj[maxn];
vector<vector<ll>> poi;
vector<ll> really;
ll n,m,i,j,s,d,u,v;
void candy(vector<ll> yui){
   poi.push_back(yui);
   for(i=0;i<poi[0].size();i++) cout<<poi[0][i]+1<<" ";
   exit(0);

}
void aka(ll u, ll d, bool visited[], ll path[], ll &path_index){
   visited[u]=true;
   path[path_index]=u;
   path_index++;
   if(u==d){
      really.clear();
      for(ll i=0;i<path_index;i++)
      really.push_back(path[i]);
      candy(really);
      return ;
   }
   else{
    sort(adj[u].begin(),adj[u].end());
    for(ll i=0;i<adj[u].size();i++)
        if(!visited[adj[u][i]]) aka(adj[u][i],d,visited,path,path_index);
   }
   path_index--;
   visited[u]=false;
}
void solve(ll s, ll d){
   bool visited[maxn];
   ll path[maxn];
   ll path_index = 0;
   for(ll i=0;i<n;i++) visited[i]=false;
   aka(s,d,visited,path,path_index);
}
int main(){
     ios_base::sync_with_stdio(false);

 cin.tie(NULL);

 cout.tie(NULL);
    cin>>n>>m>>s>>d;
    s--;
    d--;
    while(m--){
        cin>>u>>v;
        u--;v--;
        adj[u].pb(v);
    }
    solve(s,d);
   
}

Instead of getting all paths from s to t , you may try the following:您可以尝试以下方法,而不是获取从st的所有路径:
On every DFS call, assuming current node is n , get all undiscovered neighbors of n , sort them in increasing order and recursively call them starting from the smallest one.在每次 DFS 调用中,假设当前节点为n ,获取所有未发现的n邻居,按升序对它们进行排序,并从最小的一个开始递归调用它们。
Note that there is no need to reset visited status prior to returning because the very first found path from s to t is the one we need (so we don't need to inspect any other paths)请注意,在返回之前不需要重置visited状态,因为从st的第一个找到的路径是我们需要的(所以我们不需要检查任何其他路径)

Two base cases to consider:需要考虑的两个基本情况:

  1. one of neighbors of n is t n的邻居之一是t
  2. n has no undiscovered neighbors n没有未发现的邻居

Time complexity is O(V * VlogV + E)时间复杂度为O(V * VlogV + E)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM