POJ 2240
之前在POJ做过另外一道类似货币判断负环的问题,感觉那个更有挑战性也更富有变化些
这道题因为是有多组输入,为了避免一直初始化清空之前运算时用过的变量,同时也为了利用SPFA方式(从代码实现的间接性和容易成程度,应该原始的BellmanFord而非优化后的SPFA算法更合适)尝试利用类进行管理
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;
const int maxn= 35;
struct Edge
{
int f, t;
double v;
};
class SPFA
{
int n, m;
vector<Edge> G[maxn];
map<string, int> hash;
int inq[maxn], cnt[maxn];
double d[maxn];
public:
SPFA()= default;
int solve(const int nn)
{
string n_c, n_ct;
double v;
n= nn;
for (int i= 0; i< n; ++i){
cin>>n_c;
hash.insert(pair<string, int>(n_c, i));
}
scanf("%d", &m);
for (int i= 0; i< m; ++i){
cin>>n_c;
scanf("%lf", &v);
cin>>n_ct;
G[hash[n_c]].push_back((Edge){hash[n_c], hash[n_ct], v});
}
for (int i= 0; i< n; ++i){
if (!Judge(i)){
return 1;
}
}
return 0;
}
int Judge(int s)
{
queue<int> Q;
memset(d, 0, sizeof(d));
memset(inq, 0, sizeof(inq));
memset(cnt, 0, sizeof(cnt));
d[s]= 1;
Q.push(s);
inq[s]= 1;
while (!Q.empty()){
int f= Q.front();
Q.pop();
inq[f]= 0;
for (vector<Edge>::iterator gIter= G[f].begin(); G[f].end()!= gIter; ++gIter){
double v= gIter->v;
int t= gIter->t;
if (v*d[f] > d[t]){
d[t]= v*d[f];
if (!inq[t]){
Q.push(t);
inq[t]= 1;
if (++cnt[t]> n){
return 0;
}
}
}
}
}
return 1;
}
~SPFA()= default;
};
int main(int argc, char const *argv[])
{
int n;
int kase= 0;
while (~scanf("%d", &n) && n){
SPFA poj2240;
if (poj2240.solve(n)){
printf("Case %d: Yes\n", ++kase);
}
else{
printf("Case %d: No\n", ++kase);
}
}
return 0;
}