zoj 1508 Intervals

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

using namespace std;

const int INF = 10000000;
const int MAXN = 50010;

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

	ArcNode()
	{
		to = 0;
		weight = 0;
		pNext = NULL;
	}
};
ArcNode* List[MAXN];
int dist[MAXN];
int l, r;
int n;


void SPFA()
{
	queue < int > Q;
	bool inq[MAXN];
	int kcount[MAXN];
	int i;

	for (i = 0; i <= r; ++i)
	{
		inq[i] = false;
		kcount[i] = 0;
		dist[i] = INF;
	}
	kcount[r]++;
	dist[r] = 0, dist[0] = 0;
	Q.push( r );
	while (!Q.empty())
	{
		int u = Q.front();
		if(kcount[u] > n)
			return ;
		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;
					kcount[v]++;
					Q.push(v);
				}
			}
			ptr = ptr->pNext;
		}
	}
	return ;
}

void Destroy_List()
{
	int i;
	for (i = 0; i <= MAXN; ++i)
	{
		ArcNode* ptr = List[i];
		while(ptr != NULL)
		{
			List[i] = ptr->pNext;
			delete ptr;
			ptr = List[i];
		}
	}
}

int main()
{
	int i, j;
	int u, v, w;
	while (~scanf("%d", &n))
	{
		l = INF, r = 1;
		for (i = 0; i <= MAXN; ++i)
			List[i] = new ArcNode;

		for (i = 1; i <= n; ++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;

			//cout<<"****"<<endl;
			if(l > u)
				l = u;
			if(r < v)
				r = v;
		}

		for (j = 1; j <= MAXN; ++j)
        {
            ArcNode* temp = new ArcNode;
            temp->to = j;
            temp->weight = 1;
            temp->pNext = List[j-1]->pNext;
            List[j-1]->pNext = temp;

            temp = new ArcNode;
            temp->to = j-1;
            temp->weight = 0;
            temp->pNext = List[j]->pNext;
            List[j]->pNext = temp;
        }
		SPFA();
        cout<<dist[r] - dist[l-1]<<endl;
        Destroy_List();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值