要求比较大的乘积 就应该吧g[i][j] = 0
若求最短路 就把g[i][j] = INF 比较好处理


#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using std::sort; using std::queue; const int INF = 0x3f3f3f3f, MAXN = 300; bool set[MAXN]; int n, m; double g[MAXN][MAXN]; char kind[MAXN][100]; const double eps = 1e-12; // 精度处理 int minF(int a, int b) { return a<=b ?a :b ; } bool floyd() { int i, k, j; for(k=1; k<=n; k++) for(i=1; i<=n; i++) for(j=1; j<=n; j++) { double tmp = g[i][k]*g[k][j]; // 这里不能直接返回1,因为有可能g[i][j] = 0.09, tmp = 0.095 // 但g[j][i] = 10, 最后g[i][i] = 0.95 // 即还不如不换的好,它>只说明相对更优而已 if( tmp - g[i][j] > eps ) g[i][j] = tmp ; } for(i=1; i<=n; i++) if(g[i][i] - 1.0 > eps) return 1 ; return 0; } int main() { int i, j, cas = 0, k; char a[100], c[100]; double b; while(scanf("%d", &n), n!=0) { cas++; for(i=1; i<=n; i++) scanf("%s", kind[i]); scanf("%d", &m); for(i=1; i<=n; i++) for(j=1; j<=n; j++) { g[i][j] = 0; if(i == j) g[i][j] = 1; } for(k=1; k<=m; k++) { scanf("%s %lf %s", a, &b, c); for(i=1; i<=n; i++) for(j=1; j<=n; j++) if(strcmp(a, kind[i])== 0 && strcmp(c, kind[j])==0) g[i][j] = b; // 注意不是双向! } printf("Case %d: ", cas); printf("%s\n",floyd()==1?"Yes":"No"); } return 0; }