POJ 3159 - Candies(链式前向星 + 堆优化dijksta)

在幼儿园的时候,Flymouse是班上的班长。有时班主任会给班上的孩子们带来一大袋糖果,让他们分发。所有的孩子都非常喜欢糖果,经常比较他们和别人买的糖果的数量。一个孩子A可以有这样的想法,尽管可能是另一个孩子B在某些方面比他好,因此他有理由比他应得更多的糖果,但无论他实际得到多少糖果,他都不应该得到比B少的一定数量的糖果,否则他会感到不满意。 Flymouse总是把他的糖果和snoopy的比较,他想在让每个孩子都满意的同时,尽可能使自己的糖比snoopy的多。现在他又从班主任那里得到了一袋糖果,他最多能比snoopy多拿到几颗糖?

Input

输入包含单个测试用例。测试用例以两个整数n和m开始,分别不超过30000和150000。n是班上的孩子数,孩子数从1到n。snoopy和flymouse总是分别是1和n。然后按照m行,每一行依次包含三个整数a、b和c,这意味着孩子a相信孩子b永远不会比他得到的多于c颗糖果。

Output

只输出一行可能达到的最大差异。保证差异是有限的。

Sample Input

2 2
1 2 5
2 1 4

Sample Output

5

Hint

32位有符号整数类型可以执行所有算术运算。

题目大意:

输入n和m,表示班上有n个孩子和m种关系,接下来输入m行,每行包括a b c 表示孩子 a 最多只能比孩子 b 少 c 颗糖果,输出孩子1和孩子n糖果数差异的最大值。

解题思路:

理清题意后发现是最短路模板题,链式前向星存图,跑堆优化dijksta即可AC,注意这道题卡SPFA,SPFA TLE了一发。

Code:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define lowbit(x) x & (-x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 50;
const int M = 1e4 + 50;

int h[N], ne[N], e[N], w[N], idx;
int dis[N];
bool vis[N];
int n, m;

void add(int a, int b, ll c)
{
	e[idx] = b;
	w[idx] = c;
	ne[idx] = h[a];
	h[a] = idx++;
}

void dijkstra()
{
	memset(dis, 0x3f, sizeof dis);
	dis[1] = 0;

	priority_queue<pii, vector<pii >, greater<pii> > q;
	q.push({0, 1});
	
	while (!q.empty())
	{
		int u = q.top().second;
		q.pop();

		if (vis[u]) continue;
		vis[u] = true;

		for (int i = h[u]; ~i; i = ne[i])
		{
			int j = e[i];
			if (dis[u] + w[i] < dis[j])
			{
				dis[j] = dis[u] + w[i];
				q.push({dis[j], j});
			}
		}
	}
}

int main()
{
	scanf("%d%d", &n, &m);

	memset(h, -1, sizeof h);
	while (m --)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		add(a, b, c);
	}

	dijkstra();

	printf("%d\n", dis[n]);

	return 0;
}
posted @ 2020-09-17 19:52  Hayasaka  阅读(55)  评论(0编辑  收藏  举报