#include <stdio.h>
#include <iostream>
#include <map>
#include <string>
using namespace std;
#define INF 0xfffff
#define MAX 1100
float dist[MAX], path[MAX][MAX];
bool sign[MAX];
/* 注意相应权值不能为负,且时间复杂度较高 */
/*算法步骤如下:
1. 初始时令 S={V0},T={其余顶点},T中顶点对应的距离值
若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值
若不存在<V0,Vi>,d(V0,Vi)为∞
2. 从T中选取一个其距离值为最小的顶点W且不在S中,加入S
3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值
重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止
*/
void initialize(int n) //初始化
{
for(int i=1; i<=n; i++)
{
{
//pre[i] = 0;
dist[i] = 0; //将距离开始全变为最大
sign[i] = false;
}
for(int j=1; j<=n; j++)
if(i == j) path[i][j] = 1.0; //图初始
else path[i][j] = 0;
}
}
bool dijkstra(int n, int source )
{
for(int i=1; i<=n; i++)
{
dist[i] = path[source][i]; //将与源点有关的点的距离加入dist
sign[i] = false;
//if(dist[i] == INF) //确定有关系的点的前驱,无则为0
//pre[i] = 0;
//else
// pre[i] = source;
}
dist[source] = 1.0; //源点自身长度为0
sign[source] = 1;
/*
依次将未放入sign集合的结点中,取dist[]最小值的结点,放入结合sign中
一旦sign包含了所有n中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
*/
for(int i=2; i<=n; i++)
{
//int min = INF;
int current = source;
for(int j=1; j<=n; j++) //找出当前未使用点j的dist[j]的最小值
{
if( (!sign[j]) && dist[j] * path[current][j] > dist[j] )
{current = j; /*min = dist[j];*/}
}
sign[current] = true; //表示当前点最短距离已经找到
if( dist[source] > 1.0) return true;
for(int j=1; j<=n; j++) //更新当前点到未找到点的距离
//if( (!sign[j]) && path[current][j] < INF)
{
int newdist = dist[current] * path[current][j];
if(newdist > dist[j] )
{dist[j] = newdist; /*pre[j] = current;*/}
}
}return false;
}
/*void search_path(int n, int start, int end)
{
int road[MAX];
int total = 1;
road[total++] = end; //从后向前查找
int current = pre[end]; //路径存在pre中
while( current != start) //递归查找,类似并查集
{
road[total++] = current;
current = pre[current];
}
road[total] = start; //最后的开始点存入
for(int i=total; i>=1; i--) //输出
{
if( i!=1)
printf("%d ->", road[i]);
else
printf("%d\n", road[i]);
}
}*/
void input(int line)
{
map<string, int>list;
for(int i=1; i<=line; i++)
{
string temp; cin >> temp;
list[temp] = i;
}
int count;
scanf("%d", &count);
string a, b;
float weight;
for(int i=0; i<count; i++)
{
cin >> a >> weight >> b;
//if(path[list[a]][list[b]] > weight) //有多条路,保存最短的那条
{
path[list[a]][list[b]] = weight;
//path[list[b]][list[a]] = weight; //无向图双向
}
}
}
int main()
{
int n, T=0;
while(~scanf("%d", &n) && n )
{
initialize(n);
input(n);
int flag =1;
for(int i=1; i<=n; i++)
{
if(dijkstra(n, i) )
{printf("Case %d: Yes\n", ++T); flag = 0; break;}
}
if(flag) {printf("Case %d: No\n", ++T); }
}
return 0;
}
附件列表
时间: 2024-11-14 12:29:34