Algoritmo de Bellman-Ford É um pouco mais lento que dijkstra, mas é mais simples e fácil de compreender e permite pesos negativos nas arestas, enquanto que dijkstra não permite. #include <iostream> #define INFINITY 99999999 using namespace std; typedef struct { int source; int dest; int weight; } Edge; // Arestas void BellmanFord(Edge edges[], int edgecount, int nodecount, int source) { int i,j; int *distance = new int [nodecount]; for (i = 0; i < nodecount; i++) { distance[i] = INFINITY; } distance[source] = 0; for (i = 0; i < nodecount; i++) { // como otimizar este laço? for (j = 0; j < edgecount; j++) { if (distance[edges[j].dest] > distance[edges[j].source] + edges[j].weight) { distance[edges[j].dest] = distance[edges[j].source] + edges[j].weight; } } } for (i = 0; i < edgecount; i++) { if (distance[edges[i].dest] > distance[edges[i].source] + edges[i].weight) { cout << "Ciclo negativo de pesos de arestas detectado" << endl; break; } } for (i = 0; i < nodecount; i++) { cout << "Distancia menor entre nodos " << source << " e " << i <<" eh " << distance[i] << endl; } delete distance; } int main (void){ Edge Arestas[100]; int casos,nc,vertices,arestas; cin >> casos; for (nc = 0; nc < casos; nc ++){ cin >> vertices; //m cin >> arestas; for (int i=0; i< arestas; i++){ cin >> Arestas[i].source; cin >> Arestas[i].dest; cin >> Arestas[i].weight; } BellmanFord(Arestas,arestas,vertices,0); //Arestas,n de arestas,n de vertices,origem); cout << endl; } return(0); } Entrada: 2 3 3 0 1 1000 1 2 15 2 1 -42 4 4 0 1 10 1 2 20 2 3 30 3 0 -60 Saída: Ciclo negativo de pesos de arestas detectado A distancia mais curta entre os nodos 0 e 0 eh 0 A distancia mais curta entre os nodos 0 e 1 eh 919 A distancia mais curta entre os nodos 0 e 2 eh 961 A A A A distancia distancia distancia distancia mais mais mais mais curta curta curta curta entre entre entre entre os os os os nodos nodos nodos nodos 0 0 0 0 e e e e 0 1 2 3 eh eh eh eh 0 10 30 60 Análise do algoritmo Edge Arestas[100]; typedef struct { int source; int dest; int weight; } Edge; // Arestas 2 1 2 12 3 1 3 8 4 2 0 -5 5 2 3 124 6 3 4 61 7 3 6 13 8 4 0 78 9 4 5 14 10 5 1 -3 11 6 4 4 2 0 1 2 3 4 5 6 0 α α α α α α (distance[1] > distance[0] + 31) ? α > 0 + 31 ? (sim) distance[1] = 31 0 1 2 3 4 5 6 0 31 α α α α α (distance[4] > distance[0] + 78) ? α > 0 + 31 ? (sim) distance[4] = 78 distance [ ] 0 1 2 3 4 5 6 0 31 α α 78 α α (distance[2] > distance[1] + 12) ? α > 31 12 distance[2]= 43 ... 0 1 2 3 4 5 6 0 31 43 39 56 70 52 curta curta curta curta curta curta curta entre entre entre entre entre entre entre distance [ ] A A A A A A A distancia distancia distancia distancia distancia distancia distancia mais mais mais mais mais mais mais os os os os os os os nodos nodos nodos nodos nodos nodos nodos 0 0 0 0 0 0 0 4 6 Pega campo dest do vetor de Arestas (arestas[] .dest) distance [ ] 5 61 3 i distance[i] distance [ ] 1 12 14 78 8 31 4 4 1 0 -3 0 1 31 78 0 0 13 weight 4 dest 12 source -5 Arestas[ ] e e e e e e e 0 1 2 3 4 5 6 eh eh eh eh eh eh eh 0 31 43 39 56 70 52 Problemas envolvendo Bellman-Ford UVA 11492 - Babel – Facilitado (ignore restrições) sub-regional Brasil de 20 de setembro de 2008 - Problema B Joaozinho e Mariazinha são dois irmãos que estão muito empolgados com suas aulas de idiomas, cada um está fazendo vários diferentes cursinhos. Ao chegar em casa comentam sobre gramática, vocabulário, cultura dos países etc. Numa dessas conversas perceberam que algumas palavras são comuns a mais de um idioma, mesmo que não necessariamente tenham o mesmo significado. Por exemplo, “amigo” existe em português e espanhol e tem o mesmo significado, enquanto que “date” é uma palavra comum entre francês e inglês mas que pode ter significados diferentes, uma vez que “date” também se refere a um encontro em inglês, além de “data” de calendário. Já “red” em espanhol se refere a uma rede, enquanto que em inglês se refere à corvermelha. Outro exemplo seria “actual” que, em inglês significa algo real e, em espanhol, tem o significado de presente, atual (como em português). Empolgados com essas descobertas, resolveram escrever num caderno todas as palavras em comum que conseguiram pensar, associando cada uma a um par de idiomas. Observador como é, Joãozinho propôs um desafio a Mariazinha: dados um idioma de origem e um de destino, escrever uma série de palavras sendo que a primeira necessariamente deveria pertencer ao idioma de origem e a ´ultima ao de destino. Duas palavras adjacentes nessa seq¨uência deveriam necessariamente pertencer a um mesmo idioma. Por exemplo, se o idioma de origem fosse português e o de destino francês, Mariazinha poderia escrever a seq¨uência amigo actual date (português/espanhol, espanhol/inglês, inglês/francês). Restrições: Mariazinha deve encontrar a solução que tenha o menor comprimento da seqüência total não contando os espaços entre as palavras e duas palavras consecutivas não podem ter a mesma letra inicial. Sendo assim, a solução anterior passa a ser inválida, pois “amigo” e “actual” têm a mesma letra inicial. é possível, porém, encontrar outra solução, que no caso seria amigo red date, cujo comprimento total é 12. Joãozinho fez uma extensa pesquisa na internet e compilou uma enorme lista de palavras e desafiou Mariazinha a resolver o problema. Como é possível que haja mais de uma solução, ele pediu para que ela apenas respondesse o comprimento da seqüência encontrada dadas as restrições ou se não há solução possível. Você seria capaz de ajudar Mariazinha? Entrada A entrada contém vários casos de teste. A primeira linha de um caso de teste contém um inteiro M (1 <= M < 2000), representando o total de palavras compiladas por Joãozinho. A segunda linha contém duas cadeias de caracteres distintas O e D, separadas por um espaço em branco, indicando os idiomas de origem e destino respectivamente. Cada uma das M linhas seguintes contém três cadeias de caracteres I1, I2 e P, separadas por um espaço em branco, representando dois idiomas e uma palavra comum entre ambos (I1 e I2 são sempre diferentes). Todas as cadeias de caracteres terão tamanho mínimo 1 e máximo 50 e conterão apenas letras minúsculas. Um mesmo par de idiomas pode ter várias palavras diferentes associadas a ele, porém uma mesma palavra P nunca será repetida. O final da entrada é indicado por uma linha que contém apenas um zero. Saída Para cada caso de teste da entrada seu programa deve imprimir um único inteiro, o comprimento da menor seqüência que satisfaça as restrições de Joãozinho, ou impossivel (em minúsculas, sem acento) caso não seja possível. Exemplo de Entrada 4 portugues frances ingles espanhol red espanhol portugues amigo frances ingles date espanhol ingles actual 4 portugues alemao ingles espanhol red espanhol portugues amigo frances ingles date espanhol ingles actual 6 portugues frances ingles espanhol red espanhol portugues amigo frances ingles date frances espanhol la portugues ingles a espanhol ingles actual 0 Saída correspondente 12 impossivel 5 Resolução Inicialmente, deve-se entender a entrada como um grafo. Pense que as duas palavras iniciais são origem e destino e a palavra em comum entre as 2 línguas é a forma de transporte entre a origem e destino. O custo total de transporte ( distância ) entre a origem e o destino seria o tamanho da palavra em questão. Vamos supor que uma pessoa deseja ir de Gaurama até Cotegipe utilizando os meios de transporte disponíveis, escolhendo a rota cujo tamanho do meio em questão seja o menor possível. Exemplo: gaurama 0 carro van Onibus 5 gaurama cotegipe gaurama erechim onibus gaurama erechim van gaurama erechim carro erechim cotegipe onibusleito erechim cotegipe vanzinha 0 nha 2 vanzi Onib usle ito erechim cotegipe 1 O principal aqui é fazer uma entrada de dados correta para grafos. Inicia-se com a leitura do vetor de arestas. Arestas[6002] source dest weight 0 0 2 onibus 1 2 0 onibus 2 0 2 van 3 2 0 van 4 0 2 carro 5 2 0 carro 6 2 1 onibusleito 7 1 2 onibusleito 8 2 1 vanzinha 9 1 2 vanzinha A chave agora é como converter os nomes para números na leitura para armazenar no vetor de arestas (Edge) int main (void){ Edge Arestas[6002]; int casos,nc,achou,cont,tamanhostring; string origem,destino; map <string,int> mapa; cin >> casos; while (casos!=0){ mapa.clear(); cin >>origem >> destino; mapa["gaurama"] = 0; mapa[origem]=0; mapa["cotegipe"] = 1; mapa[destino]=1; tamanhostring=2; cont = 0; for (nc = 0; nc < casos; nc ++){ cin >> origem >> destino >> Arestas[cont].weight; Arestas[cont+1].weight = Arestas[cont].weight; if (mapa.find(origem)!=mapa.end()){ // encontrou achou = mapa[origem]; achou = mapa[gaurama] = 0 } else { mapa[destino]=tamanhostring; achou=tamanhostring++; } Arestas[cont].source= ... gaurama erechim onibus ... Arestas[6002] 0 1 source dest 0 weight onibus 0 onibus Obs.: o uso de maps dá um ganho de 500 % em performance comparando com uma matriz de strings na qual teríamos que pesquisar a toda a matriz a cada entrada para ver se a cidade já existe ou não na matriz. UVA 558 - Wormholes In the year 2163, wormholes were discovered. A wormhole is a subspace tunnel through space and time connecting two star systems. Wormholes have a few peculiar properties: • Wormholes are one-way only. • The time it takes to travel through a wormhole is negligible. • A wormhole has two end points, each situated in a star system. • A star system may have more than one wormhole end point within its boundaries. • For some unknown reason, starting from our solar system, it is always possible to end up in any star system by following a sequence of wormholes (maybe Earth is the centre of the universe). • Between any pair of star systems, there is at most one wormhole in either direction. • There are no wormholes with both end points in the same star system. All wormholes have a constant time difference between their end points. For example, a specific wormhole may cause the person travelling through it to end up 15 years in the future. Another wormhole may cause the person to end up 42 years in the past. A brilliant physicist, living on earth, wants to use wormholes to study the Big Bang. Since warp drive has not been invented yet, it is not possible for her to travel from one star system to another one directly. This can be done using wormholes, of course. The scientist wants to reach a cycle of wormholes somewhere in the universe that causes her to end up in the past. By travelling along this cycle a lot of times, the scientist is able to go back as far in time as necessary to reach the beginning of the universe and see the Big Bang with her own eyes. Write a program to find out whether such a cycle exists. Input The input file starts with a line containing the number of cases c to be analysed. Each case starts with a line with two numbers n and m . These indicate the number of star systems (1 <=n<=1000) and the number of wormholes ( 1 <=m<=2000) . The star systems are numbered from 0 (our solar system) through n-1 . For each wormhole a line containing three integer numbers x, y and t is given. These numbers indicate that this wormhole allows someone to travel from the star system numbered x to the star system numbered y, thereby ending up t (-1000 <= t <= 1000) years in the future. Output The output consists of c lines, one line for each case, containing the word possible if it is indeed possible to go back in time indefinitely, or not possible if this is not possible with the given set of star systems and wormholes. Sample Input 2 33 0 1 1000 1 2 15 2 1 -42 44 0 1 10 1 2 20 2 3 30 3 0 -60 Sample Output possible not possible UVA 11090 - Going in Cycle!! You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has a weight, which equals to sum of its edges. There are so many cycles in the graph with different weights. In this problem we want to find a cycle with the minimum mean. Input The first line of input gives the number of cases, N. N test cases follow. Each one starts with two numbers n and m. m lines follow, each has three positive number a, b, c which means there is an edge from vertex a to b with weight of c. Output For each test case output one line containing “Case #x: ” followed by a number that is the lowest mean cycle in graph with 2 digits after decimal place, if there is a cycle. Otherwise print “No cycle found.”. Constraints - n ≤ 50 - a, b ≤ n - c ≤ 10000000 Sample Input 5 2 1 1 2 1 2 2 1 2 2 2 1 3 3 4 1 2 12 2 1 -2 2 3 5 3 2 -6 4 5 1 2 5 2 3 2 3 1 6 3 4 3 4 3 -8 4 6 1 2 1 2 3 8 2 4 6 4 3 -1 3 2 2 3 1 6 Sample Output Case #1: No cycle found. Case #2: 2.50 Case #3: -0.50 Case #4: -2.50 Case #5: 2.33 UVA 515 - King Once, in one kingdom, there was a queen and that queen was expecting a baby. The queen prayed: ``If my child was a son and if only he was a sound king.'' After nine months her child was born, and indeed, she gave birth to a nice son. Unfortunately, as it used to happen in royal families, the son was a little retarded. After many years of study he was able just to add integer numbers and to compare whether the result is greater or less than a given integer number. In addition, the numbers had to be written in a sequence and he was able to sum just continuous subsequences of the sequence. The old king was very unhappy of his son. But he was ready to make everything to enable his son to govern the kingdom after his death. With regards to his son's skills he decided that every problem the king had to decide about had to be presented in a form of a finite sequence of integer numbers and the decision about it would be done by stating an integer constraint (i.e. an upper or lower limit) for the sum of that sequence. In this way there was at least some hope that his son would be able to make some decisions. After the old king died, the young king began to reign. But very soon, a lot of people became very unsatisfied with his decisions and decided to dethrone him. They tried to do it by proving that his decisions were wrong. Therefore some conspirators presented to the young king a set of problems that he had to decide about. The set of problems was in the form of subsequences of a sequence . The king thought a minute and then decided, i.e. he set for the sum of each subsequence Si an integer constraint ki (i.e resp.) and declared these constraints as his or decisions. After a while he realized that some of his decisions were wrong. He could not revoke the declared constraints but trying to save himself he decided to fake the sequence that he was given. He ordered to his advisors to find such a sequence S that would satisfy the constraints he set. Help the advisors of the king and write a program that decides whether such a sequence exists or not. Input The input file consists of blocks of lines. Each block except the last corresponds to one set of problems and king's decisions about them. In the first line of the block there are integers n, and m where 0 < n <=100 is length of the sequence S and 0 < m <=100 is the number of subsequences Si. Next m lines contain particular decisions coded in the form of quadruples si, ni, oi, ki, where oi represents operator > (coded as gt) or operator < (coded as lt) respectively. The symbols si, ni and ki have the meaning described above. The last block consists of just one line containing 0. Output The output file contains the lines corresponding to the blocks in the input file. A line contains text successful conspiracy when such a sequence does not exist. Otherwise it contains text lamentable kingdom. There is no line in the output file corresponding to the last ``null'' block of the input file. Sample Input 42 1 2 gt 0 2 2 lt 2 12 1 0 gt 0 1 0 lt 0 0 Sample Output lamentable kingdom successful conspiracy UVA 10702 – Traveling Salesman!! Jean is a travelling salesman. He keeps travelling among some cities. When he arrives in a city, he sells everything he has and buy new things. Then he travels to another city, sells his items and buy new ones. In this problem you will have to find the total amount of money Jean will gain on the optimal tour. On a tour he can go to some city more than once, and he must finish his tour in some cities. Also there is a starting city for his tour and the number of intercity travels he wants to do in his tour. Input The input file contains several input sets. The description of each set is given below: Each set starts with four integers C (2 ≤ C ≤ 100), the number of cities, S (1 ≤ S ≤ 100), the identifier of the starting city, E (1 ≤ E ≤ 100), the number of cities his tour can end at, and T (1 ≤ T ≤ 1000), the number of inter-city travels he wants to do. Follow C lines with C non-negative integers. The j'th integer of the i'th line will describe the profit he earns when he goes from city i to city j. As he does not want to make a trip to a city he is already, the i'th integer of the i'th line will always be 0. Note that going from city i to city j can have a different profit than going from city j to city i. After there will be a line with E integers, the identifier of the cities he can end his tour. Input is terminated by a set where C=S=E=T=0. This set should not be processed. There is a blank line beteween two input sets. Output For each input set produce one line of output, the total profit he can earn in the corresponding tour. Sample Input 3122 035 501 920 23 0000 Sample Output 7 Algoritmo de Floyd - Warshall #include <iostream> #include <iomanip> #define INFINITO 999999999 using namespace std; /* A estrutura digraph representa um digrafo. O campo adj é um ponteiro para a matriz de adjacência do digrafo. O campo Vertices contém o número de Vértices e o campo A contém o número de arcos do digrafo. */ struct digraph { int V; int A; int adj[301][301]; }; /* Um objeto do tipo Digraph contém o endereço de um digraph. */ typedef struct digraph *Digraph; void Floyd (Digraph G) { for (int k=1; k <= G->V; k++) { for (int i=1; i <= G->V; i++) { for (int j=1; j <= G->V; j++){ if ( (G->adj[j][k]+G->adj[k][i] < G->adj[j][i]) ) { G->adj[j][i]=G->adj[j][k]+G->adj[k][i]; } } } } } int main(void){ Digraph D= new (struct digraph); int i, j, vertices, arestas, origem, destino, custo; cin >> vertices >> arestas; for (i=0; i<vertices+1; i++){ for (j=0; j<vertices+1; j++){ D->adj[i][j]=INFINITO; } } D->V=vertices; D->A=arestas; for (i=0; i<arestas; i++){ cin >> origem >> destino >> custo; D->adj[origem][destino]=custo; } Floyd (D); for (i=1;i<D->V+1;i++){ // Mostra a Matriz de Adjascencia for (j=1;j<D->V+1;j++) cout << setw(12) << D->adj[i][j] << " " ; cout << endl; } return(0); } floyd.in 4 1 3 1 2 2 4 3 7 3 1 2 1 4 2 4 5 4 8 10 12 6 3 UVA – 186 – Trip Routing Your employer, the California Car Club (CCC), has decided to provide a trip routing service to its members. Your job is to write a program which reads a list of departure point-destination point pairs and calculates the shortest routes between them. For each trip, your program will print a report which itemises the names of each city passed through, with route names and leg distances. Input Input to your program will be in two parts. The first part is a map in the form of a list of highway segments. Each segment is designated by a line containing four fields which are separated by commas. The first two fields are 1-20 characters each, and are the names of the cities which are at each end of the highway segment. The third field is the 1-10 character name of the route. The fourth field is the number of miles between the two endpoints, expressed as a positive integer. The highway segment list will be terminated by an empty line. The second part of the input is a list of departure point-destination point pairs, one per line. The departure point is given first, followed by a comma and the destination point. Each of the cities is guaranteed to have appeared in the first part of the input data, and there will be a path that connects them. The list is terminated by the end of file. Output The output should be a series of reports, one for each departure point-destination point pair in the input. Each report should be in exactly the same form as those in the example below. There should be two blank lines before each report (including the first one). Sample input San Luis Obispo,Bakersfield,CA-58,117 Bakersfield,Mojave,CA-58,65 Mojave,Barstow,CA-58,70 Barstow,Baker,I-15,62 Baker,Las Vegas,I-15,92 San Luis Obispo,Santa Barbara,US-101,106 San Luis Obispo,Santa Barbara,CA-1,113 Santa Barbara,Los Angeles,US-101,95 Bakersfield,Wheeler Ridge,CA-99,24 Wheeler Ridge,Los Angeles,I-5,88 Mojave,Los Angeles,CA-14,94 Los Angeles,San Bernardino,I-10,65 San Bernardino,Barstow,I-15,73 Los Angeles,San Diego,I-5,121 San Bernardino,San Diego,I-15,103 Santa Barbara,Las Vegas San Diego,Los Angeles San Luis Obispo,Los Angeles Sample output From -------------------Santa Barbara Los Angeles San Bernardino Barstow Baker To -------------------Los Angeles San Bernardino Barstow Baker Las Vegas Route Miles ---------- ----US-101 95 I-10 65 I-15 73 I-15 62 I-15 92 ----Total 387 From To Route Miles -------------------- -------------------- ---------- ----San Diego Los Angeles I-5 121 ----Total 121 From -------------------San Luis Obispo Santa Barbara To -------------------Santa Barbara Los Angeles Route Miles ---------- ----US-101 106 US-101 95 ----Total 201 Note: There will be no extraneous blanks in the input. There will be no more than 100 cities in the map and no more than 200 highway segments. The total distance in each best route is guaranteed to fit within a 16-bit integer.