1.Question:
输入n代表有n个国家
之后的n行代表n个国家的名称
输入m代表有向边的个数
之后的代表我们国家货币之间的汇率
现在求,是否存在一条回路是的我们的交换货币之后原本的货币量增多
2.Solution:
本题是标准的判断回路的问题,我们需要将最短路的标准思路转变一下,首先,本题我们需要找到的是正权回路不是负权回路,我们只需要改变一下松弛策略就好,我们只要将松弛策略改成放大策略就ok,判断点进入队列的次数书否超过点数(这里有个问题,等于可以吗)
当然我们的Floyed算法也是可以的,我们的Floyed算法只需要判断我们的是否出现最后是否货币量比1大就好了
3.Code:
/*
Problem: 2240 User: lantianheyeqi
Memory: 376K Time: 47MS
Language: C++ Result: Accepted
*/
#include"iostream"
#include"cstring"
#include"cstdio"
#include"cstdlib"
#define N 35
using namespace std;
double dis[N];
double map[N][N];
int n,m;
char nation[35][500];
int find(char data[])
{
for(int i=1;i<=n;i++)
{
if(strcmp(nation[i],data)==0) return i;
}
}
bool SPFA()
{
memset(dis,0,sizeof(dis));
int queue[N*N*N];
int head=1;
int tail=2;
int num[N];
memset(num,0,sizeof(num));
bool book[N];
memset(book,0,sizeof(book));
queue[1]=1;
book[1]=1;
dis[1]=1;
num[1]=1;
while(head!=tail)
{
for(int i=1;i<=n;i++)
{
if(dis[i] < dis[queue[head]]*map[queue[head]][i])
{
dis[i] = dis[queue[head]]*map[queue[head]][i];
if(book[i] == 0)
{
book[i]=1;
queue[tail++]=i;
num[i]++;
if(num[i] > n) return true;
}
}
}
book[queue[head]]=0;
head++;
}
return false;
}
int main()
{
int t=1;
while(scanf("%d",&n)&&n!=0)
{
memset(map,0,sizeof(map));
for(int i=1;i<=n;i++) scanf("%s",nation[i]);
scanf("%d",&m);
double edge;
char n1[500];
char n2[500];
int flag=0;
for(int i=1;i<=m;i++)
{
scanf("%s %lf %s",n1,&edge,n2);
int index1 = find(n1);
int index2 = find(n2);
map[index1][index2] = edge ;
if(index1 == index2 && edge > 1)
{
printf("Case %d: Yes\n",t++);
flag=1;
break;
}
}
if(flag == 1) continue;
bool judge = SPFA();
if(judge) printf("Case %d: Yes\n",t++);
else printf("Case %d: No\n",t++);
}
return 0;
}