Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.07 KB | None | 0 0
  1. #include <vector>
  2. #include <queue>
  3. #include <stack>
  4. #include <climits>
  5. #include <iostream>
  6.  
  7. using namespace std;
  8.  
  9. #define INFINITO INT_MAX
  10.  
  11. class DisjointSets { // Classe de implementação da estrutura de dados “conjuntos disjuntos”
  12.  
  13. private:
  14. vector<int> DJ;
  15. public:
  16. DisjointSets(int size) : DJ(size) {
  17. for(int u=0; u<size; u++)
  18. DJ[u]=u;
  19. }
  20. int SET(int n) {
  21. if(DJ[n]==n)
  22. return n;
  23. else
  24. return DJ[n] = SET(DJ[n]);
  25. }
  26. int UNION(int n1, int n2) {
  27. return DJ[ SET(n1) ] = SET(n2);
  28. }
  29. };
  30.  
  31. template <class PESO>
  32. class Graph {
  33. private:
  34. // V é um vetor de Vertices, E um vetor de Arestas
  35. int V, E;
  36. // ADJ vetor de nós adjacentes
  37. vector< vector<int> > adj;
  38. // WEIGHT é um vetor de pesos, nos respectivos nós.
  39. vector< vector<PESO> > weight;
  40.  
  41. // Construtor que recebe como parâmetro o número de nós, adicionando um vetor de adj com número de nós
  42. // Vetor de WEIGHT com número de nós e Vetor de Vértices com o número de nós, e E (Arestas) vazio.
  43. public:
  44. Graph(int nodes): adj(nodes), weight(nodes),
  45. V(nodes), E(0)
  46. { }
  47.  
  48. //Retorna o número de vértices
  49. inline int getNodes() {return V;}
  50. // retorna o numero de arestas (E)
  51. inline int getEdges() {return E;}
  52.  
  53. // conecta dois vértices (indices) "u" e "v" com peso W
  54. void addEdge(int u, int v, PESO w) {
  55. // inserindo no final o adjacente de u que é o v.
  56. adj[u].push_back(v);
  57. // inserindo peso no nó U.
  58. weight[u].push_back(w);
  59. //conta o numero de arestas.
  60. E++;
  61. }
  62. // verifica se há conexão em dois vértices.
  63. bool hasEdge(int u, int v) {
  64. // numero de nós que ele aponta.
  65. int degree = adj[u].size();
  66. for(int i=0; i<degree; i++) {
  67. // percorre todos os nós e verifica se existe uma ligação com o nó que foi passado como
  68. // parametro(v).
  69.  
  70. if(adj[u][i]==v)
  71. return true;
  72. }
  73.  
  74. return false;
  75. }
  76. //busca em largura
  77. // recebe o indice inicial para percorrer o grafo.
  78. vector<int> bfs(int s) {
  79. // inicia o vetor de verificação visitados como sendo false.
  80. vector<bool> visited(V, false);
  81. //fila de visitados.
  82. queue<int> q;
  83. // vetor de retorno de visitados
  84. vector<int> ret;
  85.  
  86. //adiciona o nó inicial na fila
  87. q.push(s);
  88. // marca o nó inicial como visitado(true).
  89. visited[s] = true;
  90.  
  91. // enquanto a pilha não for vazia
  92. while(!q.empty()) {
  93. // retira o primeiro elemento da fila.
  94. int u = q.front();
  95. // remove o elemento da fila.
  96. q.pop();
  97.  
  98. // adiciona o visitado no vetor de retorno.
  99. ret.push_back(u);
  100.  
  101. // percorre todas as arestas "i" do nó "u".
  102. for(int i=0; i<adj[u].size(); i++) {
  103. // v recebe o índice do nó adjacente ao nó u
  104. int v = adj[u][i];
  105. // verifica se ja foi visitado, caso nao ;
  106. if(visited[v]==false) {
  107. // adiciona na fila de visitados
  108. q.push(v);
  109. // e marca ele como visitado
  110. visited[v] = true;
  111. }
  112. }
  113. }
  114. // retorna a sequencia de visitados pelo algoritmo BFS
  115. return ret;
  116. }
  117.  
  118. // busca em profundidade
  119. vector<int> dfs(int s) {
  120. // marca todos como não visitados (false)
  121. vector<bool> visited(V, false);
  122. // pilha de visitados
  123. stack<int> st;
  124. // vetor de retorno de visitados
  125. vector<int> ret;
  126.  
  127. st.push(s); // insere “s” na pilha
  128. visited[s] = true; // marca nó como visitado
  129.  
  130. //enquanto a pilha não estiver vazia
  131. while(!st.empty()) {
  132. // retira o último elemento inserido na pilha
  133. int u = st.top();
  134. st.pop();
  135.  
  136. // adiciona o nó visitado no vetor de retorno
  137. ret.push_back(u);
  138.  
  139. // busca por um vizinho não visitado
  140. for(int i=0; i<adj[u].size(); i++) {
  141. // v recebe o índice do nó adjacente (adj) ao nó u
  142. int v = adj[u][i];
  143. if(visited[v]==false) {
  144. // se não foi visitado adiciona a pilha de visitados
  145. st.push(v);
  146. // marca como visitado
  147. visited[v] = true;
  148. }
  149. }
  150. }
  151. // retorna a sequência de visitados pelo algoritmo DFS
  152. return ret;
  153. }
  154.  
  155. //algoritmo de dijkstra
  156. int Dijkstra(int s, int d){
  157. vector<bool> visited(V, false); //inicia um vetor com os vértices não visitados
  158.  
  159. vector<PESO> cost(V, INFINITO); //define o custo para todos os vertices como infinito
  160. cost[s] = 0; //o vertice inicial é definido com custo 0
  161.  
  162. priority_queue< pair<PESO, int>,
  163. vector< pair<PESO, int> >,
  164. greater< pair<PESO, int> > > q;
  165.  
  166. q.push( pair<PESO, int>(0, s) ); //enfileira o vertice inicial
  167.  
  168. while(!q.empty()) { //enquanto a fila não estiver vazia
  169. pair<PESO, int> p = q.top();
  170. q.pop(); //retira da fila
  171. int v = p.second;
  172. PESO costV = p.first;
  173. if(visited[v]) continue;
  174.  
  175. if(v==d) return cost[d]; //se chegou ao vértice de destino para e retorna o custo total
  176.  
  177. visited[v] = true; //marca o vertice como visitado
  178.  
  179. for(int i=0; i<adj[v].size(); i++) { // itera sobre o vetor de adjacencias
  180. int neigh = adj[v][i]; //define o vizinho
  181. if(cost[v]+weight[v][i]<cost[neigh]){ //se o custo do vértice atual mais o peso da aresta for menor que o custo do vizinho
  182. cost[neigh] = cost[v]+weight[v][i]; //o vizinho recebe o novo custo menor
  183. q.push( pair<PESO,int>(cost[neigh], neigh) );
  184. }
  185. }
  186. }
  187.  
  188. } //Dijkstra
  189.  
  190. vector<int> topSort() {
  191. queue<int> q;
  192. vector<int> inDegree(V, 0);
  193. vector<int> ret;
  194.  
  195. for(int u=0; u<V; u++) {
  196. for(int i=0; i<adj[u].size(); i++) {
  197. int v = adj[u][i];
  198. // aresta u para v
  199. inDegree[v]++;
  200. }
  201. }
  202.  
  203. for(int u=0; u<V; u++) {
  204. if(inDegree[u]==0)
  205. q.push(u);
  206. }
  207.  
  208. //Enquanto a fila nao estiver vazia
  209. while(!q.empty()) {
  210. int u = q.pop();
  211. ret.push_back(u);
  212.  
  213. for(int i=0; i<adj[u].size(); i++) {
  214. int v = adj[u][i];
  215. inDegree[v]--;
  216. if(inDegree[v]==0)
  217. q.push(v);
  218. }
  219. }
  220. return ret;
  221. }//topsort
  222.  
  223. // Algoritmo de Kruskal
  224. PESO Kruskal() {
  225. PESO sum = 0;
  226.  
  227. // Cria um vetor de arestas e seus respectivos pesos
  228. vector< pair<PESO, pair<int,int> > > edges;
  229.  
  230. // Inicializa todas as arestas e seus pesos
  231. for(int u=0; u<V; u++) {
  232. for(int i=0; i<adj[u].size(); i++) {
  233. int v = adj[u][i];
  234. pair<int,int> p(u, v);
  235. pair<PESO, pair<int,int> > e(weight[u][i], p);
  236. edges.push_back(e);
  237. }
  238. }
  239.  
  240. // Ordena o vetor de arestas
  241. //sort(edges.begin(), edges.end() );
  242.  
  243. /*
  244. Inicializa estrutura conjuntos disjuntos
  245. Utilizada para verificar se uma aresta já está na MST de forma rápida.
  246. */
  247. DisjointSets dj(V);
  248.  
  249. for(int i=0; i<edges.size(); i++) {
  250. pair<int,int> p = edges[i].second;
  251. int u = p.first;
  252. int v = p.second;
  253. // Se u e v estão em conjuntos distintos
  254. if(dj.SET(u) != dj.SET(v)) {
  255. //soma os pesos das arestas, representando o custo da MST
  256. sum += edges[i].first;
  257.  
  258. // Coloca u e v no mesmo conjunto
  259. dj.UNION(u, v);
  260. //cout << u << " para " << v << " = " << edges[i].first << endl;
  261. }
  262. }
  263.  
  264. return sum;
  265. } //Kruskal
  266.  
  267. PESO Prim() {
  268. vector<bool> visited(V, false); //inicia um vetor com os vértices não visitados
  269. vector<PESO> cost(V, INFINITO); //define o custo para todos os vertices como infinito
  270.  
  271.  
  272. PESO sum = 0;
  273. cost[0] = 0;
  274.  
  275. priority_queue< pair<PESO, int>,
  276. vector< pair<PESO, int> >,
  277. greater< pair<PESO, int> > > q;
  278.  
  279. q.push( pair<PESO, int>(0/*cost*/, 0/*node*/) );
  280.  
  281. //Enquanto a Fila não estiver vazia
  282. while(!q.empty()) {
  283. pair<PESO, int> p = q.top(); //Recupera o próximo da fila
  284. q.pop(); //Remove da fila
  285. int v = p.second;
  286. PESO costV = p.first;
  287. if(visited[v]) continue; //Caso tenha sido visitado: ignore-o
  288.  
  289. //cout << "v = " << v << endl;
  290.  
  291. visited[v] = true; //Marca como visitado
  292. sum += cost[v]; //Incrementa o Custo Total
  293.  
  294. for(int i=0; i<adj[v].size(); i++) {
  295. int neigh = adj[v][i];
  296. if(weight[v][i]<cost[neigh]){
  297. cost[neigh] = weight[v][i];
  298. q.push( pair<PESO, int>( cost[neigh], neigh) );
  299. }
  300. }
  301.  
  302.  
  303. } //while(q)
  304. return sum;
  305. }//Prim
  306. };
  307.  
  308. int main() {
  309. //Mapeia o grafo
  310. //Cria um grafo com 6 vertices
  311. Graph<int> g(6);
  312.  
  313. //Adiciona as arestas no grafo
  314. g.addEdge(1, 2, 5);
  315. g.addEdge(1, 4, 10);
  316. g.addEdge(2, 1, 7);
  317. g.addEdge(2, 3, 1);
  318. g.addEdge(2, 4, 15);
  319. g.addEdge(2, 5, 3);
  320. g.addEdge(3, 2, 9);
  321. g.addEdge(3, 5, 34);
  322. g.addEdge(4, 1, 5);
  323. g.addEdge(4, 2, 16);
  324. g.addEdge(4, 5, 6);
  325. g.addEdge(5, 2, 9);
  326. g.addEdge(5, 3, 6);
  327. g.addEdge(5, 4, 1);
  328.  
  329. cout << "Menor Custo: " << g.Dijkstra(1, 2) << endl;
  330. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement