zoj 2770 Burn the Linked Camp

Bellman_Ford实现:点击打开http://blog.csdn.net/hearthougan/article/details/17631941

差分约束系统的SPFA实现:SPFA速度比Bellman_Ford快多了。链表实现,表头不存数据。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>

using namespace std;

const int INF = 10000000;
const int MAXN = 1010;

struct ArcNode
{
	int to;
	int weight;
	ArcNode* pNext;

	ArcNode()
	{
		to = 0;
		weight = 0;
		pNext = NULL;
	}
};

ArcNode* List[MAXN];

int n;
int dist[MAXN];
bool inq[MAXN];

bool SPFA()
{
	int i;
	int kcount[MAXN];
	queue < int > Q;
	for (i = 0; i <= n; ++i)
	{
		dist[i] = INF;
		inq[i] = false;
		kcount[i] = 0;
	}
	dist[0] = 0;
	dist[n] = 0;
	Q.push( n );
	kcount[n]++;

	while (!Q.empty())
	{
		int u = Q.front();
		if(kcount[u] > n)
			return false;
		Q.pop();
		inq[u] = false;

		ArcNode* ptr = List[u]->pNext;

		while (ptr != NULL)
		{
			int v = ptr->to;
			if(dist[v] > dist[u] + ptr->weight)
			{
				dist[v] = dist[u] + ptr->weight;
				if(!inq[v])
				{
					inq[v] = true;
					Q.push(v);
					kcount[v]++;
				}
			}
			ptr = ptr->pNext;
		}
	}
	return true;
}

int main()
{
	int m;
	int u, v, w;
	int i;
	int d[MAXN];
	int C[MAXN];
	while (~scanf("%d %d",&n, &m))
	{
		memset(d, 0, sizeof(d));
		memset(C, 0, sizeof(C));
		for (i = 0; i <= n; ++i)
		{
			List[i] = new ArcNode;
		}
		for (i = 1; i <= n; ++i)
		{
			cin>>C[i];
			ArcNode* temp = new ArcNode;
			temp->to = i;
			temp->weight = C[i];
			temp->pNext = List[i-1]->pNext;
			List[i-1]->pNext = temp;

			temp = new ArcNode;
			temp->to = i-1;
			temp->weight = 0;
			temp->pNext = List[i]->pNext;
			List[i]->pNext = temp;
			d[i] = C[i] + d[i-1];
		}

		for (i = 0; i < m; ++i)
		{
			cin>>u>>v>>w;
			ArcNode* temp = new ArcNode;
			temp->to = u-1;
			temp->weight = -w;
			temp->pNext = List[v]->pNext;
			List[v]->pNext = temp;

			temp = new ArcNode;
			temp->to = v;
			temp->weight = d[v] - d[u-1];
			temp->pNext = List[u-1]->pNext;
			List[u-1]->pNext = temp;
		}

		if(SPFA())
			cout<<dist[n] - dist[0]<<endl;
		else
			cout<<"Bad Estimations"<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值