POJ 1860

Bellman-ford算法的队列优化,SPFA的应用,数据结构和算法结合真是太精妙了

当然这道题不幸贡献了两发WA,原因是我愚蠢的忘记了货币值的数组应该开成浮点数,第二次则是因为输出没有'\n'(这个题目的叙述很不好,这样结尾根本没法判断有无换行符)

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;

const int maxn= 105;

struct Edge
{
	int f, t;
	double r, c;	
};
int n, m, s;
double v;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn], cnt[maxn];
double d[maxn];

void AddEdge(int &f, int &t, double &r, double &c)
{
	edges.push_back((Edge){f, t, r, c});
	G[f].push_back(edges.size()-1);
}
bool Bellman(int s, double v)
{
	queue<int> Q;
	memset(inq, 0, sizeof(inq));
	memset(cnt, 0, sizeof(cnt));
	memset(d, 0, sizeof(d));
	d[s]= v;
	inq[s]= 1;
	Q.push(s);

	while (!Q.empty()){
		int u= Q.front();
		Q.pop();
		inq[u]= 0;

		for (vector<int>::iterator gIter= G[u].begin(); G[u].end()!= gIter; ++gIter){
			Edge &eg= edges[*gIter];
			if ((d[u]-eg.c)*eg.r > d[eg.t]){
				d[eg.t]= (d[u]-eg.c)*eg.r;
				if (!inq[eg.t]){
					Q.push(eg.t);
					inq[eg.t]= 1;
					if (++cnt[eg.t] > n){
						return false;
					}
				}
			}
		}
	}

	return true;
}

int main()
{
	scanf("%d %d %d %lf", &n, &m, &s, &v);
	int a, b;
	double ra, ca, rb, cb;
	for (int i= 0; i< m; ++i){
		scanf("%d %d %lf %lf %lf %lf", &a, &b, &ra, &ca, &rb, &cb);
		AddEdge(a, b, ra, ca);
		AddEdge(b, a, rb, cb);
	}
	if (Bellman(s, v)){
		printf("NO\n");
	}
	else{
		printf("YES\n");
	}
	return 0;
}
posted @ 2021-04-05 22:52  IdiotNe  阅读(36)  评论(0编辑  收藏  举报