Algorithm 如何在图G中打印负循环?

Algorithm 如何在图G中打印负循环?,algorithm,graph,cycle,bellman-ford,Algorithm,Graph,Cycle,Bellman Ford,如何在有向加权图中找到负循环。我知道Bellman-Ford算法是如何工作的,它告诉我是否存在可达到的负循环。但它没有明确地命名它 如何获得循环的实际路径v1,v2,…vk,v1 在应用标准算法之后,我们已经完成了n−1次迭代,不可能进一步改进。如果我们仍然可以降低到节点的距离,则存在负循环 假设边(v,u)是bellman-ford算法在第n次迭代中失败的边-d(u)>d(v)+w(v,u)。 所以我们知道v,u是负周期的一部分,但问题是如何检测特定周期?为了解决这个问题,我们使用贝尔曼-福特

如何在有向加权图中找到负循环。我知道Bellman-Ford算法是如何工作的,它告诉我是否存在可达到的负循环。但它没有明确地命名它

如何获得循环的实际路径v1,v2,…vk,v1

在应用标准算法之后,我们已经完成了n−1次迭代,不可能进一步改进。如果我们仍然可以降低到节点的距离,则存在负循环

假设边(v,u)是bellman-ford算法在第n次迭代中失败的边-d(u)>d(v)+w(v,u)。
所以我们知道v,u是负周期的一部分,但问题是如何检测特定周期?

为了解决这个问题,我们使用贝尔曼-福特算法。为了打印循环,我们将节点的父节点存储在向量(par)中。也可以有多个循环,所以在第n次迭代中,我们找到-ve循环。因此,我们制作一个访问数组,然后转到循环的开始,而不是使用par(父向量),我们可以找到循环的路径。 我的代码可以帮助你

#include <bits/stdc++.h>
#include <iostream>
using namespace std; 
#define ll long long 
int main(){
    int n,m;
    cin>> n>>m;
    vector<vector<pair<int,ll int > >>graph(n+1);
    for(int i=0;i<m;i++){
       ll int a,b,c;
       cin>> a>> b>> c;
       graph[a].push_back({b,c});
    }

    vector<ll int >dist(n+1,1e14),par(n+1,-1);

    // applying bellman ford algo.

    for(int i=1;i<n;i++){
       for(int j=1;j<=n;j++){
           for(auto k:graph[j]){
                ll int node=k.first,c=k.second;
                if(dist[node]>c+dist[j]){
                    dist[node]=c+dist[j];
                    par[node]=j;
                }
           }
       }
    }


    // checking nth iteration 


    bool flag=false;
    for(int i=1;i<=n;i++){
       for(auto k:graph[i]){
          ll int node=k.first,c=k.second;
          if(dist[node]>c+dist[i]){
             dist[node]=c+dist[i];
             par[node]=i;
             flag=true;
          }
            
          if(flag){

            // negative cycle founded
            
            cout<<"YES cycle founded"<<endl;

            vector<int >ans;
            vector<bool>vis(n+1,false);


            //  loop for finding the start of cycle
            while(!vis[i]){
                vis[i]=true;
                i=par[i];
            }

            
            // pushing the nodes of path in vector(ans).

            int u=i;
            ans.push_back(u);
            u=par[u];
            while(u^i){
                ans.push_back(u);
                u=par[u];
            }
            ans.push_back(u);
            reverse(ans.begin(),ans.end());


            //printing path

            for(auto z:ans)cout<<z<<" ";
            return 0;
            }
       }
    }   

    if(!flag)cout<<"NO cycle founded"<<endl;
}
#包括
#包括
使用名称空间std;
#定义ll long long
int main(){
int n,m;
cin>>n>>m;
矢量图(n+1);
对于(inti=0;i>a>>b>>c;
图[a]。推回({b,c});
}
矢量分布(n+1,1e14),par(n+1,-1);
//应用贝尔曼福特算法。

对于(int i=1;i来解决这个问题。我们使用bellman-ford算法。为了打印循环,我们将节点的父节点存储在一个向量(par)中。也可以有多个循环,因此在第n次迭代中,我们找到-ve循环。因此,我们创建一个访问数组,并转到循环的开始,而不是使用par(父向量)我们可以找到循环的路径。 我的代码可以帮助你

#include <bits/stdc++.h>
#include <iostream>
using namespace std; 
#define ll long long 
int main(){
    int n,m;
    cin>> n>>m;
    vector<vector<pair<int,ll int > >>graph(n+1);
    for(int i=0;i<m;i++){
       ll int a,b,c;
       cin>> a>> b>> c;
       graph[a].push_back({b,c});
    }

    vector<ll int >dist(n+1,1e14),par(n+1,-1);

    // applying bellman ford algo.

    for(int i=1;i<n;i++){
       for(int j=1;j<=n;j++){
           for(auto k:graph[j]){
                ll int node=k.first,c=k.second;
                if(dist[node]>c+dist[j]){
                    dist[node]=c+dist[j];
                    par[node]=j;
                }
           }
       }
    }


    // checking nth iteration 


    bool flag=false;
    for(int i=1;i<=n;i++){
       for(auto k:graph[i]){
          ll int node=k.first,c=k.second;
          if(dist[node]>c+dist[i]){
             dist[node]=c+dist[i];
             par[node]=i;
             flag=true;
          }
            
          if(flag){

            // negative cycle founded
            
            cout<<"YES cycle founded"<<endl;

            vector<int >ans;
            vector<bool>vis(n+1,false);


            //  loop for finding the start of cycle
            while(!vis[i]){
                vis[i]=true;
                i=par[i];
            }

            
            // pushing the nodes of path in vector(ans).

            int u=i;
            ans.push_back(u);
            u=par[u];
            while(u^i){
                ans.push_back(u);
                u=par[u];
            }
            ans.push_back(u);
            reverse(ans.begin(),ans.end());


            //printing path

            for(auto z:ans)cout<<z<<" ";
            return 0;
            }
       }
    }   

    if(!flag)cout<<"NO cycle founded"<<endl;
}
#包括
#包括
使用名称空间std;
#定义ll long long
int main(){
int n,m;
cin>>n>>m;
矢量图(n+1);
对于(inti=0;i>a>>b>>c;
图[a]。推回({b,c});
}
矢量分布(n+1,1e14),par(n+1,-1);
//应用贝尔曼福特算法。

对于(int i=1;i)如何使用u(或v)作为源再次运行Bellman Ford,以及如何使用n次迭代而不是n-1。在某一点上,u.d如何使用u(或v)作为源再次运行Bellman Ford,以及如何使用n次迭代而不是n-1。在某一点上,u.d