关于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
。。。