1. 程式人生 > >最短路(bellman)-hdu1217

最短路(bellman)-hdu1217

 

Dijkstra演算法是處理單源最短路徑的有效演算法,但它侷限於邊的權值非負的情況,若圖中出現權值為負的邊,Dijkstra演算法就會失效,求出的最短路徑就可能是錯的。

這時候,就需要使用其他的演算法來求解最短路徑,Bellman-Ford演算法就是其中最常用的一個。

由於此題中需要求的是有一種貨幣A,通過一系列的轉化,能夠再次轉化回A,因此,運用bellman演算法來解決此題。

具體的關於bellman最短路的求法請見轉載部落格:http://www.cnblogs.com/aiguona/p/7226533.html

題目連結:https://vjudge.net/problem/HDU-1217

題目描述:

程式碼描述:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <iostream>
using namespace std;

const int MAX_E  = 1000;
const int MAX_V = 33;
const int INF = 0x3f3f3f3f;
struct node{
    int from,to;
    double cost;
}es[MAX_E*4];//用於存圖
int cae=0; int V,E; double d[MAX_V]; map<string,int> mp;//將字串問題轉換為數字問題 bool bellman(int s){ //fill(d,d+MAX_V,-2); for(int i=0;i<MAX_V;i++){ d[i]=-99999999; } d[s]=1;//是初始值為1,假設某人有1塊錢,用這1塊錢去做交換 for(int j=0;j<V;j++){//進行反覆鬆弛操作,使得每個節點的最短距離估計值逐步逼近其最短距離 bool update=false
; for(int i=0;i<E;i++){ if(d[es[i].from]!=-99999999 && d[es[i].to] < d[es[i].from]*es[i].cost){ if(j==V-1){ return true; } d[es[i].to]=d[es[i].from]*es[i].cost; update=true; } } if(!update) break;//優化這裡,如果這趟沒跟新任何節點就可以直接退出了。 } return false; } void solve(){ bool flag=false; for(int i=0;i<V;i++){//對於每一種存在的貨幣來說,都遍歷一遍 if(bellman(i)){//如果說存在一種貨幣能夠轉換回來並且盈利,則成功,可直接退出 flag=true; break; } } if(flag){ cout << "Case " << ++cae << ": Yes" << endl; }else{ cout << "Case " << ++cae << ": No" << endl; } } int main(){ //ios::sync_with_stdio(false)的用法:詳見部落格 https://blog.csdn.net/vocaloid01/article/details/77892490
ios::sync_with_stdio(false);//這樣就可以取消cin於stdin的同步,使得cin的效率與scanf差不多 while(cin>> V && V){ mp.clear(); for(int i=0;i<V;i++){ string str; cin >> str; mp[str]=i;//將str的“下標”賦值為i,即為了方便後續存圖,用數字i來代替字串str } cin >> E; map<string,int>::iterator it;//迭代器用於遍歷map中的元素 for(int i=0;i<E;i++){ string str1,str2; double cost; cin >> str1 >> cost >> str2; it=mp.find(str1);//查詢函式,即找到str1在mp中的位置 es[i].from=it->second;//將找到的str1對應的“下標”,將結點i的起點值賦值為str1所對應的下標值 it=mp.find(str2); es[i].to=it->second;//將找到的str2對應的“下標”,將結點i的終點值賦值為str1所對應的下標值 es[i].cost=cost;//把結點i由起點from->to所對應的邊的邊長賦值為cost } solve(); } return 0; }