Dijkstra+堆优化

关于dijkstra,我们应该比较熟悉了,今天讲的是dijkstra的堆优化(O(ElogN)l)(如果连dijkstra都不知道的小朋友给你一个网址:http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html)。

我们先来看一题:

网吧

【问题背景】

    绵阳中学以人数众多而闻名。三个年级共有10000 多人,学生多了附近的网吧也多。Mzoiers 都热衷于Dota,可学校的机子配置相当差(评测服务器除外),根本不能玩Dota,那就只有去网吧。星期天到星期五都是晚上10:20 才下晚自习,几乎没时间玩。

    然而星期六下午放假是绝好的时间,但是学校人多啊,一放学去网吧的人就开始狂奔,竞争之激烈,抢到机子的难度非常之大。往往在我们到达网吧之前都坐满了。

    学校到网吧的路是错综复杂的,以致于到一个自己想去的网吧都有非常多的路线可以选择,而路线的长度又不相同,这样就决定了要花费的时间,因此想要尽快到达,选择一条最佳的线路是很有必要的。

【问题描述】

    为了简化问题,我们把学校与周边的网吧看做图中的顶点,学校与网吧,网吧与网吧之间的路线看做边,每个边都有一个权,表示我们走完这条路的时间,由于放学人流量大,如果反向走会有危险,因此这是一个有向图。

    我的的学校在S点,想要去的网吧在T点。你的任务就是选择一条最佳路线,使得从学校到目的地网吧的时间最短,你只需要输出最短到达时间即可。

【输入文件】

    netbar.in 中共有M+2 行数据

    第一行两个整数N,M,表示点数和边数。

    然后M行每行3个正整数(u,v,t),表示有一条可由u 到v耗时为t的边。

    最后一行两个正整数S、T。

【输出文件】

     netbar.out中,只有一行,一个整数表示最短时间。如果S、T之间不存在通路则输出“No Solution!”(双引号不输出,“!”为西文标点)。

【输入样例】

    4 4

    1 2 3

    2 4 10

    1 3 5

    3 4 5

    1 4

【输出样例】

    10

【数据规模】

    对于30%的数据保证有1

    对于全部的数据保证有1

错解:spfa,预计得分:30,原因:数据太大,以spfa O(kE)的复杂度很有可能超时。下面给上spfa的代码:

#include
#include
#include
#include
#include
#include
#include
#define inf 99999999
using namespace std;
struct fow{
	int v;
	int t;
};
struct fow2{
	int bs;
	int point;
};
vector  q[10020];
queue  qu;
int tb[10020]={0},bo[10020];
int n,m,x,y,z;
int main()
{
	freopen("netbar.in","r",stdin);
	freopen("netbar.out","w",stdout);
	int ans=inf;
	for(int i=0;i<=10000;i++)bo[i]=inf;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		fow zz;zz.v=y;zz.t=z;
		q[x].push_back(zz);
		tb[x]++;
	}
	int s,t;
	scanf("%d%d",&s,&t);
	if(s==t)
	{
		printf("0");
		return 0;
	}
	fow2 z1;
	z1.bs=0;
	z1.point=s;
	qu.push(z1);
	while(!qu.empty())
	{
		int now=qu.front().point;
		int ntime=qu.front().bs;
		qu.pop();
		for(int i=0;i

正解:dijkstra+堆优化,在原有的dijkstra的基础下,在寻找周围最小点的时候,用最小堆,就可以用O(log n)的时间找出最小的可到达点。其实感觉用了堆之后,这种做法极像spfa。还有,我用的是STL的优先队列。。。。

代码:

#include
#include
#include
#include
#include
#include
#include
#define Maxn 100020
using namespace std;
struct fow1{
	int v;
	int t;
};
struct fow{
	int point;
	int time;
};
struct cmp{
	bool operator()(fow a,fow b)
	{
		return a.time,cmp>q;
vector qu[Maxn];
int tx[Maxn];
bool bo[Maxn];
int main()
{
	freopen("netbar.in","r",stdin);
	freopen("netbar.out","w",stdout);
	int n,m;
	int x,y,z;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		fow1 zz;zz.v=y;zz.t=z;
		qu[x].push_back(zz);
		++tx[x];
	}
	int s,t;
	scanf("%d%d",&s,&t);
	if(s==t)
	{
		printf("0");
		return 0;
	}
	fow z1;z1.point=s;z1.time=0;
	q.push(z1);
	while(!q.empty())
	{
		int now=q.top().point;	
		int ntime=q.top().time;
		q.pop();
		for(int i=0;i
。。。



你可能感兴趣的:(日常水)