Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<vector>
- #include<iostream>
- class edge
- {
- public :
- int from , to , weight ;
- edge(){};
- edge (int mfrom , int mto , int mweight )
- {
- from = mfrom ;
- to = mto ;
- weight = mweight;
- }
- };
- int dfs ( int vert , std::vector<std::vector<int>>& graph , std::vector<bool>& visited )
- {
- int result = 1;
- visited[vert] = true ;
- for (int i = 0 ; i < graph[vert].size() ;++i )
- {
- if (!visited[graph[vert][i]])
- result += dfs ( graph[vert][i] , graph , visited);
- }
- return result ;
- }
- void dfs_topological (int vert , std::vector<std::vector<int>>& graph ,
- std::vector<bool>& visited , std::vector<int>& topological)
- {
- visited[vert] = true ;
- for (int i = 0 ; i < graph[vert].size() ; ++i)
- {
- if (!visited [graph[vert][i]])
- dfs_topological( graph[vert][i] , graph , visited , topological);
- }
- topological.push_back(vert);
- }
- void dfs_components(int vert , int& count, std::vector<std::vector<int>>& graph ,
- std::vector<bool>& visited , std::vector<int>& components)
- {
- visited[vert] = true;
- for (int i = 0 ; i < graph[vert].size() ; ++i)
- {
- if (!visited[graph[vert][i]])
- dfs_components(graph[vert][i], count , graph , visited, components);
- }
- components[vert] = count ;
- }
- std::vector<int> topologicalSort (std::vector<std::vector<int>>& graph )
- {
- std::vector<int> topological ;
- std::vector<bool> visited (graph.size() , false );
- for (int i = 0 ; i < graph.size() ; ++i)
- {
- if (!visited[i])
- dfs_topological(i , graph , visited , topological);
- }
- return topological ;
- }
- std::vector<int> findComponents (std::vector<std::vector<int>>& graph ,
- std::vector<std::vector<int>>& t_graph,int&count)
- {
- std::vector<int> components (graph.size());
- std::vector<int> topological = topologicalSort (graph);
- std::vector<bool> visited (graph.size() , false );
- for (int i = topological.size() - 1; i >= 0 ; --i)
- {
- if (!visited[topological[i]])
- {
- dfs_components(topological[i] , count , t_graph , visited , components );
- count++;
- }
- }
- return components ;
- }
- void rechargeGraph ( std::vector<edge>& edges ,std::vector<std::vector<int>>& graph ,
- std::vector<std::vector<int>>& t_graph )
- {
- for (int i = 0 ; i < edges.size() ; ++i)
- {
- graph[edges[i].from].push_back(edges[i].to);
- t_graph[edges[i].to].push_back(edges[i].from);
- }
- }
- long long int findMST ( int n ,std::vector<edge>& edges ,int root )
- {
- long long int answer = 0 ;
- std::vector<int> min_edges (n,2000000000);
- for (int i = 0 ; i < edges.size() ; ++i)
- {
- min_edges[edges[i].to] = min_edges[edges[i].to] < edges[i].weight ? min_edges[edges[i].to] : edges[i].weight;
- }
- for (int i = 0 ; i < n ; ++i)
- {
- if (i != root)
- answer += min_edges[i];
- }
- std::vector<edge> zeroEdges ;
- for (int i = 0 ; i < edges.size() ; ++i)
- {
- if (edges[i].weight ==min_edges[edges[i].to])
- {
- edge box (edges[i].from,edges[i].to,edges[i].weight-min_edges[edges[i].to]);
- zeroEdges.push_back(box);
- }
- }
- std::vector<std::vector<int>> graph(n) ;
- std::vector<std::vector<int>> t_graph(n);
- std::vector<bool> visited (t_graph.size(),false);
- rechargeGraph(zeroEdges , graph , t_graph);
- if (dfs(root , graph , visited)==n)
- {
- return answer ;
- }
- int count = 0 ;
- std::vector<int> components = findComponents(graph , t_graph, count );
- std::vector<edge> newEdges;
- for (int i = 0 ; i < edges.size() ; ++i)
- {
- if (components[edges[i].from]!=components[edges[i].to])
- {
- edge box (components[edges[i].from],components[edges[i].to],edges[i].weight -
- min_edges[edges[i].to]);
- newEdges.push_back(box);
- }
- }
- answer += findMST(count , newEdges,components[root]);
- return answer;
- }
- int main ()
- {
- int n , m ;
- std::cin>>n>>m;
- int v1 , v2 , weight ;
- std::vector<edge> edges(m);
- std::vector<std::vector<int>> graph(n);
- std::vector<std::vector<int>> t_graph (n);
- for (int i = 0 ; i < m ; ++i)
- {
- std::cin>>v1>>v2>>weight;
- edge box (v1 - 1, v2 -1 , weight);
- edges[i] = box;
- }
- std::vector<bool> visited (n,false);
- rechargeGraph(edges , graph , t_graph);
- if (dfs(0 , graph ,visited)==n)
- {
- std::cout<<"YES"<<"\n";
- std::cout<<findMST(n , edges , 0);
- }
- else
- {
- std::cout<<"NO";
- }
- return 0 ;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement