您的位置:首页 > 其它

POJ-1860 Currency Exchange

2015-12-14 13:37 253 查看
发现对bellman-ford和spfa对负环的判断模糊。

bellman-ford:判断负环.进行n-1次循环过后。如果还能松弛。表明有负环

spfa :某点入队列超过n次,表明有负环

后来发现了bellman-ford的一个小优化算法。

就是在循环里面立一个flag,如果在n-1次之前没有松弛成功,直接跳出表明全部已经完成。

spfa 有一点需要注意,就是if(++num[nxt]>N) return 0;别放入if的判断条件里面,如果需要松弛,无论该点是否之前在队列里面,那么现在一定要在队列里面。所以进入队列的次数一定要增加。

Code

#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include<sstream>
#include <cmath>
using namespace std;
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define INF 1001000
#define sq(x) (x)*(x)
#define eps (1e-10)
#define clr(x) memset((x),0,sizeof (x))
#define cp(a,b) memcpy((a),(b),sizeof (b))

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int maxn=110;

vector<pair<int,pair<double,double> > > G[maxn];
int vis[maxn];
int num[maxn];
double dist[maxn];
int N,M,S;
double V;

int spfa(int s)
{
clr(dist);
clr(vis);
clr(num);
dist[s]=V;
queue<int> q;
q.push(s);
++num[s];
while(!q.empty())
{
int now=q.front();q.pop();
vis[now]=0;
for(int i=0;i<G[now].size();i++)
{
int nxt=G[now][i].fs;
double v=G[now][i].se.fs;
double c=G[now][i].se.se;
if(dist[nxt]<(dist[now]-c)*v)
{
dist[nxt]=(dist[now]-c)*v;
//printf("%lf\n",dist[nxt]);
if(!vis[nxt])
{
q.push(nxt);
vis[nxt]=1;
}
if(++num[nxt]>N) return 0;
}
}
}
return 1;
}

int main()
{
scanf("%d%d%d%lf",&N,&M,&S,&V);
for(int i=1;i<=N;i++)
{
G[i].clear();
}
for(int i=0;i<M;i++)
{
int a,b;
double R1,C1,R2,C2;
scanf("%d%d%lf%lf%lf%lf",&a,&b,&R1,&C1,&R2,&C2);
G[a].pb(make_pair(b,make_pair(R1,C1)));
G[b].pb(make_pair(a,make_pair(R2,C2)));
}
int k=spfa(S);
if(!k) printf("YES\n");
else          printf("NO\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: