您的位置:首页 > 其它

POJ2240_SPFA判断负环,Floyd也可以做(计算最大汇率,当自己到自己的最大汇率大于1时成立)

2017-07-14 18:02 447 查看
//因为vector的P[]没有clear所以疯狂wa

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<vector>
#include<string>
#include<map>
#include<cstdio>
#define Max 0x3f3f3f3f
using namespace std;
map<string, int> M;
const int maxn = 50;
double Map[maxn][maxn];
int cnt[maxn];
bool vis[maxn];
bool book[maxn];
vector<int> P[maxn];
double D[maxn];
bool boo[maxn][maxn];
int Du[maxn];

bool spfa(int id, int n)//找与id节点相连接的负环
{
queue<int> Q;
memset(D, 0, sizeof(D));
D[id] = 1.0;
memset(cnt, 0, sizeof(cnt));
memset(vis, 0, sizeof(vis));
Q.push(id);
vis[id] = 1;
book[id] = 1;
cnt[id]++;
while (!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = false;
for (int i = 0; i < P[u].size(); i++)
{
int v = P[u][i];//u的终结点
if (!book[v])
{
book[v] = 1;
}
double tt = D[u]*Map[u][v];
if (tt > D[v])
{
D[v] = tt;
if (!vis[v])
{
vis[v] = true;
Q.push(v);
cnt[v]++;
if (cnt[v] > Du[v])//其实只要大于这个点的入度就行
return true;
}
}
}
}
return false;
}

int main()
{
int n;
int cas = 1;
while (~scanf("%d", &n) && n)
{
memset(Du, 0, sizeof(Du));
cout << "Case " << cas++ << ": ";
string s;
M.clear();
int c = 1;
for (int i = 0; i < n; i++)
{
cin >> s;
P[i].clear();
if (M[s] == 0)
{
M[s] = c++;
}
}

n = c - 1;
int m;
cin >> m;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Map[i][j] = 0;
}
}
string s0, s1;
double r;
memset(boo, 0, sizeof(boo));
for (int i = 0; i < m; i++)
{
cin >> s0 >> r >> s1;
int x = M[s0]-1;
int y = M[s1]-1;
Map[x][y] = r;
boo[x][y] = 1;
}

for (int i = 0; i < n; i++)
{
for (int j = 0; j <n ; j++)
{
if (boo[i][j])
{
P[i].push_back(j);
Du[j]++;
}
}
}
memset(book, 0, sizeof(book));
bool ans = false;
for (int i = 0; i < n; i++)
{
if (!book[i])//这一步是一处优化
{
if (spfa(i, n))
{
ans = true;
break;
}
}
}

if (ans)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: