本文主要是介绍poj 1860 SPFA,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
心累才是最可怕的,好几天没上poj,这样不行,明天开始,继续每天一题。
如题:http://poj.org/problem?id=1860
给出一张各种货币交换的网络,问在网络中交换原有的货币,问货币能否增值?
1.当图中存在正权环时,肯定货币是可以增值的。
2.不存在正权环时,也有可能增值,用spfa算法,松弛操作修改求大的值,如果dist[src]>v(v是原有的钱数),也是可以增值的。
3.2条都不行,不能增值。
注意是双向边,边表大小是2倍。
用静态邻接表实现SPFA即可。
#include<iostream>
using namespace std;
#include<queue>
//#define inf 0x0fffffff
#define MAXN 105
#define MAXM 105
int head[MAXN];
int next[MAXM*2];
double dis[MAXN];
int vis[MAXN];
int cnt[MAXN];
double v;
struct note
{
double rate,commission;
int u,v;
note(){}
note(int u,int v,double rat,double com):u(u),v(v),rate(rat),commission(com){}
}p[MAXM*2];
int e,n,m;
void addnote(int u,int v,double r,double c)
{
p[e]=note(u,v,r,c);
next[e]=head[u];
head[u]=e++;
}
int spfa(int s)
{
int i;
for(i=1;i<=n;i++)
dis[i]=-1;
dis[s]=v;
vis[s]=true;
queue<int>que;
que.push(s);
cnt[s]=1;
while(!que.empty())
{
int pre=que.front();
que.pop();
vis[pre]=false;
double cur=dis[pre];
for(i=head[pre];i!=-1;i=next[i])
{
int v=p[i].v;
double r=p[i].rate;
double c=p[i].commission;
double tmp=(cur-c)*r;
if(tmp>dis[v])
{
dis[v]=tmp;
if(!vis[v])
{
que.push(v);
cnt[v]++;
vis[v]=1;
if(cnt[v]>n)
return true;
}
}
}
if(dis[s]>v)
return true;
}
return false;
}
int main()
{
int s;
// freopen("C:\\1.txt","r",stdin);
scanf("%d%d%d%lf",&n,&m,&s,&v);
memset(head,-1,sizeof(head));
// memset(next,-1,sizeof(next));
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
e=0;
int i;
for(i=0;i<m;i++)
{
int u,v;
double r1,c1,r2,c2;
scanf("%d%d%lf%lf%lf%lf",&u,&v,&r1,&c1,&r2,&c2);
addnote(u,v,r1,c1);
addnote(v,u,r2,c2);
}
if(spfa(s))
printf("YES\n");
else
printf("NO\n");
return 0;
}
这篇关于poj 1860 SPFA的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!