Пожалуйста, прочтите новое правило об ограничении использования AI-инструментов. ×

Блог пользователя Vedkribhu

Автор Vedkribhu, история, 4 года назад, По-английски

Problem: Link I was using Bellman Ford to solve this. To detect a cycle in bellman ford we usually do one more pass on the edges (after n-1) passes and see if anything updated, if yes there is a cycle. But in this problem even if there is a cycle in graph but not a part of path between vertex 1 and n is tolerable. How to detect when to print -1?

  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

»
4 года назад, # |
  Проголосовать: нравится +2 Проголосовать: не нравится

Run the Bellman-Ford Algorithm for the nth iteration and mark the nodes whose distance is changed. Now reverse the adjacency list and run a DFS from node 'n'. If at least one of the nodes marked is visible from n, then the answer is -1, else the answer is the maximum distance from 1 to n.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Can you please explain the intuition behind doing this?

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Only to check that, does a positive cycle in the graph affects the 'nth' node, if it does, then it is sure that answer is -1, else answer is the max distance.

      Ex:

      7 7

      1 2 1

      2 7 1

      1 6 -1

      6 5 -1

      5 4 -1

      4 3 -1

      3 1 5

      here, the +ve cycle affects the 'nth' node.

      But here,

      8 9

      1 2 1

      2 3 1

      3 4 1

      4 2 1

      1 8 1

      5 8 1

      5 6 1

      6 7 1

      7 5 1

      it doesn't affect the nth node.

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Reason behind marking nodes whose distances are changed in the nth iteration — node which is marked is involved in the cycle. We will print -1 only when it is possible to reach to last node from the cycle. To check whether it is possible to reach to last node from the cycle, there are two ways 1) run dfs from every node which is marked (involved in cycle) and check whether is it possible to reach to nth node, if yes print — 1. 2)reverse the graph and check whether it is possible to reach to atleast one node which is marked from the last node, if yes print -1. Both ways give the same result but the 2nd method is fast. Please ask if you have any doubt(this is my first explanation, I apologize if my explanation is not clear).

      • »
        »
        »
        »
        18 месяцев назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        The first approach can be optimized by inserting all those nodes into a queue and running a bfs. Depending on the data structure used to store the graph it can be simpler or more complicated than the second one. If there is an adjacency array for every node then the bfs is simpler, but for an array of edges the dfs is much simpler since there is no need to reverse the edges.

  • »
    »
    4 года назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    what if the node (in the cycle and connected to n) is not connected to 1?
    1 4 1
    2 4 1
    2 3 1
    3 2 1
    there's a cycle 2 — 3 — 2 and 2 is connected to 4 but even then, answer is still 1 (and not -1) because we can't go to that cycle

    what I did was see everyone that could be in a path from 1 to n, if one of those nodes are in a cycle, answer is -1:

    run dfs from 1 in original graph, mark everyone connected
    run dfs from n in reversed graph, mark everyone connected
    intersection is the vertices that we can use in our path, and if any vertex here is in a cycle, ans is -1

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Nodes that are not reachable from node 1 will always remain unchanged i.e INFINITY in the distance array. so only dfs from n'th node in reverse adj list is fine .

    • »
      »
      »
      16 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      nice, then we can mark each node in 2 criteria
      reachable_from_node_1_normal
      reachable_from_node_n_reverse

      If, after N iterations, both boolean values above are true, then the answer = -1.

»
3 года назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
2 1
1 2 -1

Answer is -1, but it isn't infinity score.

?

»
21 месяц назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится
idea
code
»
3 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

include

include

include

include

include

include

include

include

include

define ll long long int

using namespace std; bool dfs(vector<vector<pair<ll,ll> > >&v,vector&changed,ll st,vector&vis){ if(changed[st] ){ return 1; } vis[st]=1;

for(auto adj:v[st]){
    if(!vis[adj.first]){

   if( dfs(v,changed,adj.first,vis)){
    return 1;
   }
    }
}
return 0;

}

int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int t=1; //cin>>t; while(t--){ ll n,m; cin>>n>>m; vector<pair<ll,pair<ll,ll> > >v(m); vector<vector<pair<ll,ll> > >v2(n+1); for(int i=0;i<m;i++){ ll a,b,c; cin>>a>>b>>c; v[i]=make_pair(a,make_pair(b,c)); v2[b].push_back(make_pair(a,c)); } vectorans(n+1,-1e18); ans[1]=0;

for(int i=1;i<=n-1;i++){

        for(int j=0;j<m;j++){
            ll a=v[j].first;
            ll b=v[j].second.first;
            ll c=v[j].second.second;

            if(ans[a]!=-1e18 && ans[a]+c>ans[b]){
                ans[b]=ans[a]+c;
            }
        }
    }
    vector<ll>changed(n+1,0);

      for(int i=0;i<m;i++){
            ll a=v[i].first;
            ll b=v[i].second.first;
            ll c=v[i].second.second;


            if(ans[a]!=-1e18 && ans[a]+c>ans[b]){
             ans[b]=ans[a]+c;
             changed[b]=1;

            }

        }
        vector<ll>vis(n+1,0);

        bool check=dfs(v2,changed,n,vis);
        if(check){
            cout<<-1<<endl;
            continue;
        }
        cout<<ans[n]<<endl;












 }

}

THATS HOW YOU CAN SOLVE IT