POJ3159 Candies(最短路径:SPFA+链表+栈)

96 篇文章 0 订阅
48 篇文章 0 订阅

题意:

有n个同学分糖,给m组数据i,j,k,要求第j个同学分到的糖不能比第i个同学分到的糖多于k个。要求第1个同学与第n个同学之间糖的个数差距最大,求最大的差距。

要点:

这题思路不难,既然要求1~n的差距最大,那每组数据刚好取k,整个就是一个最短路问题,dis数组存储的就是最多拿到的糖。但这题时间卡的实在是太紧,SPFA用STL都会超时,而且数据太大,必须要用邻接表存储边。所以看了一下网上大神的代码,用一个栈来维护原本的队列,然后用链表来存储同一个起点的所有边,这样可以到450ms,这题也说明了SPFA算法的时间不稳定。还可以用dijstra+heap做。


15391447Seasonal3159Accepted1960K454MSC++1078B2016-04-14 16:43:44

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 0x3f3f3f3f

struct edge
{
	int v, len;
	int next;
}e[150005];
int dis[30005],adj[30005];
bool vis[30005];
int n, m,tot;//tot为总边数

void add_edge(int u, int v, int len)//增加同一个起点的边数,链表存储
{
	e[tot].v = v;
	e[tot].len = len;
	e[tot].next = adj[u];//如果只有一条边就是-1
	adj[u] = tot++;		//adj用来指向下一个终点对应的下标
}

void spfa()
{
	memset(dis, INF, sizeof(dis));
	memset(vis, true, sizeof(vis));
	int stack[30005];
	int top = 0;
	stack[++top] = 1;
	vis[1] = false;
	dis[1] = 0;
	while (top)
	{
		int u = stack[top--];	//stack堆栈用来存储起点
		vis[u] = true;
		for (int i = adj[u]; i != -1; i = e[i].next)//遍历同一个起点的所有终点
		{
			int v = e[i].v;
			int len = e[i].len;
			if (dis[v] > dis[u] + len)
			{
				dis[v] = dis[u] + len;
				if (vis[v])
				{
					stack[++top] = v;
					vis[v] = false;
				}
			}
		}
	}
	
}

int main()
{
	int u, v, len;
	scanf("%d%d", &n, &m);
	for (int i = 0; i <= n; i++)
		adj[i] = -1;
	tot = 0;
	while(m--)
	{
		scanf("%d%d%d", &u,&v,&len);
		add_edge(u, v, len);
	}
	spfa();
	printf("%d\n", dis[n]);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值