题意:问从一点出发然后回到这一点,是否存在一条路径其权值相乘大于1.0。
思路:用bellman算法可以求出一点到其他点的最短距离,bellman进行了n-1次递推,若我们进行n次递推则可以求出一点到自身的最短距离。而这题其实是求最长路,稍作改变即可。
代码:
#include <iostream>
#include <string>
#include <cstdio>
#include <map>
using namespace std;
const int inf = 100000000;
const int maxn = 35;
const int maxm = 500;
int n,m;
double dist[maxn];
map<string,int> Map;
double edge[maxn][maxn];
bool Input(){
cin>>n;
if(n == 0) return false;
string t;
for(int i = 0; i < n; i++){
cin>>t;
Map[t] = i;
}
cin>>m;
string u,v;
double w;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++)
if(i == j) edge[i][j] = 0;
else edge[i][j] = -inf;
}
for(int i = 0; i < m; i++){
cin>>u>>w>>v;
edge[Map[u]][Map[v]] = w;
}
return true;
}
void Bellman(int s){
for(int i = 0; i < n; i++){
dist[i] = edge[s][i];
}
for(int i = 0; i < n -1; i++){
for(int v = 0; v < n; v++){
for(int u = 0; u < n; u++){
if(dist[u] * edge[u][v] > dist[v]){
dist[v] = dist[u] * edge[u][v];
}
}
}
}
}
void Solve(){
static int cnt = 0;
bool ok = false;
for(int i = 0; i < n; i++){
Bellman(i);
if(dist[i] > 1.0){
ok = true;
break;
}
}
if(ok) printf("Case %d: Yes\n",++cnt);
else printf("Case %d: No\n",++cnt);
}
int main(){
while(Input()){
Solve();
Map.clear();
}
return 0;
}