代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
struct edge{int v;double w;};
vector<edge>g[50050];
int vis[50050];
int ji[50050];
double dis[50050];
map<string,int>mp;
int n;
int t=0;
int spfa(int st){
vis[st]=1;
dis[st]=1;
queue<int>q;
q.push(st);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=0;i<g[u].size();i++){
int v=g[u][i].v;
double w=g[u][i].w;
if(dis[u]*w>dis[v]){
dis[v]=dis[u]*w;
if(!vis[v]){
ji[v]++;
if(ji[v]>n)
return 1;
vis[v]=1;
q.push(v);
}
}
}
}
return 0;
}
int main(){
while(cin>>n){
t++;
int cnt=0;
mp.clear();
for(int i=0;i<=n;i++)
g[i].clear();
memset(vis,0,sizeof(vis));
memset(ji,0,sizeof(ji));
memset(dis,0,sizeof(dis));
if(n==0)
break;
for(int i=1;i<=n;i++){
string s;
cin>>s;
if(!mp[s])
mp[s]=++cnt;
}
int m;
cin>>m;
for(int i=1;i<=m;i++){
string s,t;
double w;
cin>>s>>w>>t;
g[mp[s]].push_back((edge){mp[t],w});
}
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
memset(ji,0,sizeof(ji));
memset(dis,0,sizeof(dis));
int ok=spfa(i);
if(ok){
cout<<"Case "<<t<<": "<<"Yes"<<endl;
break;
}
if(i==n&&ok==0)
cout<<"Case "<<t<<": "<<"No"<<endl;
}
}
return 0;
}
注意清空,刚开始dis[st]是一个大于0的数,其他点为0,在松弛过程中,没有环就正常松弛,有环就在第二次松弛时看会不会增大。
此外还有Floyd做法