题目链接:https://vjudge.net/problem/POJ-2240
又是一道判断负环的题,这次用spfa做,先用了一般的bfs版的spfa
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
const int N=30+2;
int n,m;
double g[N][N];
double d[N];
bool vis[N];
bool spfa()
{
int cnt[N];
for(int i=0;i<n;i++)
d[i]=0.0;
memset(vis,false,sizeof(vis));
memset(cnt,0,sizeof(cnt));
d[0]=100;
vis[0]=true;
cnt[0]=1;
queue<int> q;
q.push(0);
while(!q.empty())
{
int u=q.front();
vis[u]=false;
q.pop();
for(int i=0;i<n;i++)
if(d[i]<d[u]*g[u][i])
{
d[i]=d[u]*g[u][i];
if(!vis[i])
{
cnt[i]++;
if(cnt[i]>=n) return true;
q.push(i);
}
vis[i]=true;
}
}
return false;
}
int main()
{
int kase=0;
while(~scanf("%d",&n)&&n)
{
map<string,int> mm;
string a,b;
double c;
for(int i=0;i<n;i++)
{
cin>>a;
mm[a]=i;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
g[i][j]=0.0;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
cin>>a>>c>>b;
g[mm[a]][mm[b]]=c;
}
printf("Case %d: ",++kase);
if(spfa()) printf("Yes\n");
else printf("No\n");
}
return 0;
}
然后听说dfs优化的spfa判断负环更好些,结果是对这道题来说时间差不多
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
const int N=30+2;
int n,m;
double g[N][N];
double d[N];
bool vis[N],flag;
void spfa(int u)
{
if(flag) return;
for(int i=0;i<n;i++)
if(d[i]<d[u]*g[u][i])
{
if(vis[i])
{
flag=true;
return;
}
else
{
d[i]=d[u]*g[u][i];
vis[i]=true;
spfa(i);
vis[i]=false;
}
}
}
int main()
{
int kase=0;
while(~scanf("%d",&n)&&n)
{
map<string,int> mm;
string a,b;
double c;
for(int i=0;i<n;i++)
{
cin>>a;
mm[a]=i;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
g[i][j]=0.0;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
cin>>a>>c>>b;
g[mm[a]][mm[b]]=c;
}
for(int i=0;i<n;i++)
d[i]=0.0;
d[0]=100;
memset(vis,false,sizeof(vis));
vis[0]=true;
flag=false;
spfa(0);
printf("Case %d: ",++kase);
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}