POJ3259 农场与虫洞 图论(Bellman-Ford求负环)

嗯图论的第二道题,刚刚有一点点入门的感觉www。

于是就把心得体会写下来啦。

题目概述:

主人公农夫有几片农场,然后农场里有各个农田(这个模型化为图的端点),然后各个农田之间有路径(这个模型化为图的边),然后有的边是正常的无向边,以及有的边是有项的虫洞。开始的时候时间为0,通过一条正常边会加时间,通过虫洞减去时间。

输入N(1-500),M(1-2500),W(1-100),然后输出能否通过一条路径回到过去,也就是模型中的负权环。

算法思想:

求负权显然的Bellman-Ford,可是还是太慢了要400多MS,不知道先进的方法是怎么样的。果然要看下SPFA么。。

大概跟标准模版无差,值得一提的是,这种算法求负权环有两种方式,第一种是求完最短路径然后继续检查更新,第二种是直接看更新能不能进行到第n-1次,两种代码我都实现了一遍,速度也并没有太大的差异。就列在下面了。

代码部分:

代码1:

#include <iostream>
using namespace std;
int N;int n,m,w;
int MAX = 21474836;

struct edge{
	int from,to,cost;
};

int d[555];bool flag;
edge e[5600];

void init() {
	flag = false;
	cin >> n >> m >> w;
	for (int i=0;i<n;i++){
		d[i] = MAX;
	}
	d[0] = 0;
	for (int i=0;i<2*m;i+=2){
		int a,b,c;
		cin >> a >> b >> c;
		e[i].from = a;
		e[i].to = b;
		e[i].cost = c;
		e[i+1].from = b;
		e[i+1].to = a;
		e[i+1].cost = c;
	}
	for (int i=2*m;i<2*m+w;i++){
		int a,b,c;
		cin >> a >> b >> c;
		e[i].from = a;
		e[i].to = b;
		e[i].cost = c*(-1);
	}
}

bool b_f() {
	for (int i=0;i<n-1;i++){
		for (int j=0;j<2*m+w;j++){
			if (d[e[j].from] != MAX && d[e[j].to] > d[e[j].from]+e[j].cost) {
				d[e[j].to] = d[e[j].from]+e[j].cost;
			}
		}
	}

	for (int j=0;j<2*m+w;j++){
		if (d[e[j].to] > d[e[j].from]+e[j].cost) {
			return true;
		}
	}
	return false;

}


int main() {
	cin >> N;
	for (int k=0; k<N; ++k){
		init();
		if (b_f()) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}

代码2:

#include <iostream>
#include <string.h>
using namespace std;
int N;int n,m,w;

struct edge{
	int from,to,cost;
};

int d[555];
edge e[5600];

void init() {
	cin >> n >> m >> w;
	memset(d,0,sizeof(d));
	for (int i=0;i<m*2;i+=2){
		int a,b,c;
		cin >> a >> b >> c;
		e[i].from = a;
		e[i].to = b;
		e[i].cost = c;
		e[i+1].from = b;
		e[i+1].to = a;
		e[i+1].cost = c;
	}
	for (int i=2*m;i<2*m+w;i++){
		int a,b,c;
		cin >> a >> b >> c;
		e[i].from = a;
		e[i].to = b;
		e[i].cost = c*(-1);
	}
}

bool b_f() {
	for (int i=0;i<n;i++){
		for (int j=0;j<2*m+w;j++){
			if (d[e[j].to] > d[e[j].from]+e[j].cost) {
				d[e[j].to] = d[e[j].from]+e[j].cost;
				if (i == n-1) return true;
			}
		}
	}
	return false;
}


int main() {
	cin >> N;
	for (int k=0; k<N; ++k){
		init();
		if (b_f()) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/Oh233/article/details/42237893
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞