题意大概就是给你一个有向图,让你判断是否存在正环(图不一定连通)。不一样的是,每个顶点都是一个字符串,不过不要紧,我们可以用一个map<string,int>,把他们改为整型数据。
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cctype>
#include<map>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
int fa[35],inq[35],cnt[35];
double mon[35];
map<string,int> mp;
struct exchange
{
int id;
double r;
};
vector<exchange> G[35];
int find(int root)
{
int son=root,temp;
while(root!=fa[root])
root=fa[root];
while(son!=root)
{
temp=fa[son];
fa[son]=root;
son=temp;
}
return root;
}
void unite(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
fa[fx]=fy;
}
bool Bellman_Ford(int n)
{
queue<int> Q;
for(int i=1;i<=n;i++)
{
cnt[i]=0;
inq[i]=0;
if(fa[i]==i)
{
mon[i]=1.0;
inq[i]=1;
Q.push(i);
}
else mon[i]=0.0;
}
while(!Q.empty())
{
int u=Q.front(); Q.pop();
inq[u]=0;
for(int i=0;i<G[u].size();++i)
{
exchange e=G[u][i];
if(mon[u]>0&&mon[e.id]<mon[u]*e.r)
{
mon[e.id]=mon[u]*e.r;
if(!inq[e.id])
{
Q.push(e.id);
inq[e.id]=1;
if(++cnt[e.id]>n)
return true;
}
}
}
}
return false;
}
int main()
{
int n,m,kase=0;
while(cin>>n)
{
if(!n) break;
for(int i=1;i<=n;i++)
{
string t;
cin>>t;
mp[t]=i;
fa[i]=i;
}
cin>>m;
for(int i=1;i<=m;i++)
{
string f,t; double rate;
cin>>f>>rate>>t;
int u; exchange v;
u=mp[f]; v.id=mp[t]; v.r=rate;
unite(u,v.id);
G[u].push_back(v);
}
if(Bellman_Ford(n))
cout<<"Case "<<++kase<<": Yes\n";
else cout<<"Case "<<++kase<<": No\n";
mp.clear(); //map还有vector记得清空
for(int i=1;i<=n;i++)
G[i].clear();
}
return 0;
}
注意:这道题得用队列优化,否则可能会超时(本人TLE了一次)