POJ - 3159 Candies最大差异

题目链接
题意
n个人分糖果,有m个约束条件,a认为b不能比他多c个糖果,求1和n的最大糖果数量差。
思路
约束条件等价为num[a] + c >= num[b]。相当于从a到b有一条等于c的有向边,这样就转换为了最短路问题,直接用dijkstra求1到n的最短路即可。

参考大佬博客
由p[j] - p[i] <= k可得p[j] <= p[i] + k
在单源最短路径的算法中有一步是“若mindis[j] > mindis[i] + dis[i][j],则mindis[j] = mindis[i] + dis[i][j],这样就满足mindis[j] <= mindis[i] + dis[i][j]”。因此本题可以使用单源最短路径的算法来解决,对于“第i个同学要求第j个同学的糖不能超过自己k个,即p[j] - p[i] <= k,k >= 0”这个条件,建立一条边(i->j)=k,然后用最短路算法求解。

#include <iostream>
#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
#define pr pair<int, int>

const int MAXN = 1e5;
int head[MAXN], to[MAXN<<1], nex[MAXN<<1], n, m;
int edge[MAXN<<1], cnt;
int d[MAXN];
bool final[MAXN];
int t, s, e;
void init()
{
	memset(head, -1, sizeof(head));
	cnt = 0;
}

void add(int x, int y, int val)
{
	to[++cnt] = y;
	edge[cnt] = val;
	nex[cnt] = head[x];
	head[x] = cnt;
}
int dijkstra()
{
	memset(final, 0, sizeof(final));
	memset(d, INF, sizeof(d));
	priority_queue<pr, vector<pr>, greater<pr> > q;
	q.push(make_pair(0, s));//firstÊÇlength,secondÊǶ¥µã
	d[s] = 0;
	while (!q.empty())
	{
		int u = q.top().second;
		q.pop();
		final[u] = true;
		for (int i = head[u]; ~i; i = nex[i])
		{
			int v = to[i];
			int len = edge[i];
			if(!final[v] && d[v] > d[u] + len)
			{
				d[v] = d[u] + len;
				q.push(make_pair(d[v], v));
			}
		}
	}
	return d[e];
}
int main()
{
	init();
	scanf("%d %d", &n, &m);
	s = 1, e = n;
	int x, y;
	int val;
	for (int i = 1; i <= m; i++)
	{
		scanf("%d %d %d", &x, &y, &val);
		add(x, y, val);
	}
	printf("%d\n", dijkstra());
}

发布了26 篇原创文章 · 获赞 2 · 访问量 410

猜你喜欢

转载自blog.csdn.net/D_Bamboo_/article/details/103546484