poj1860:从自己的币种出发,如果发现正环,那么则可以不停地走环路以增加自己手中的价值.题目转换成寻找正环。
poj2240:遍历每一个点,设币为1元,如果发现正环,则可以增长前。两种代码spfa&floyd
poj1860:
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <cstdio>
#include <string>
#include<string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int n,m,s;
double v;
double c[110][110],r[110][110];
inline void read(int &m)
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
m=x*f;
}
bool spfa()
{
double d[110];
for(int i=1;i<=n;i++) d[i]=-111111;
d[s]=v;
queue<int>que;
que.push(s);
int cnt=0;
while(!que.empty())
{
if(cnt>n*n)return 1;
int v=que.front();
que.pop();
cnt++;
for(int i=1;i<=n;i++)
if(r[v][i]>=0&&(d[v]-c[v][i])*r[v][i]>d[i])
{
d[i]=(d[v]-c[v][i])*r[v][i];
que.push(i);
}
}
return 0;
}
int main()
{
cin>>n>>m>>s>>v;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
r[i][j]=-1.0;
for(int i=1;i<=m;i++)
{
int a,b;
double c1,r1,c2,r2;
cin>>a>>b>>r1>>c1>>r2>>c2;
c[a][b]=c1;
c[b][a]=c2;
r[a][b]=r1;
r[b][a]=r2;
}
if(spfa())
cout<<"YES\n";
else
cout<<"NO\n";
return 0;
}
poj2240:
spfa
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <cstdio>
#include <string>
#include<string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
map<string,int>mm;
int n,m;
double graph[40][40];
bool spfa(int s)
{
double d[40];
for(int i=1;i<=n;i++) d[i]=-111111;
d[s]=1;
int cnt=0;
queue<int>que;
que.push(s);
while(!que.empty())
{
if(cnt++>n*n)
return 1;
int v=que.front();
que.pop();
for(int i=1;i<=n;i++)
if(graph[v][i]>=0&&d[i]<d[v]*graph[v][i])
{
d[i]=d[v]*graph[v][i];
que.push(i);
}
}
return 0;
}
int main()
{
int num=1;
while(scanf("%d",&n),n)
{
memset(graph,-1.0,sizeof(graph));
for(int i=1;i<=n;i++)
{
string st;
cin>>st;
mm[st]=i;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
string st1,st2;
double d;
cin>>st1>>d>>st2;
graph[mm[st1]][mm[st2]]=d;
}
printf("Case %d: ",num++);
int i;
for(i=1;i<=n;i++)
if(spfa(i))
{
printf("Yes\n");
break;
}
if(i>n)
printf("No\n");
}
return 0;
}
floyd:
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <cstdio>
#include <string>
#include<string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
map<string,int>mm;
int n,m;
double graph[40][40];
void floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(graph[i][k]*graph[k][j]>graph[i][j])
graph[i][j]=graph[i][k]*graph[k][j];
}
int main()
{
int num=1;
while(scanf("%d",&n),n)
{
memset(graph,0,sizeof(graph));
for(int i=1;i<=n;i++)
{
string st;
cin>>st;
mm[st]=i;
graph[i][i]=1;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
string st1,st2;
double d;
cin>>st1>>d>>st2;
graph[mm[st1]][mm[st2]]=d;
}
floyd();
bool ok=0;
printf("Case %d: ",num++);
for(int i=1;i<=n;i++)
if(graph[i][i]>1)
{
printf("Yes\n");
ok=1;
break;
}
if(ok) continue;
printf("No\n");
}
return 0;
}