您的位置:首页 > 编程语言 > C语言/C++

[SDOI2010]魔法猪学院(Astar 优化K短路)

2017-10-22 21:44 274 查看

题目描述

题目太长了,大致说一下大意

有n个点,m条路,e(浮点型)的流量,接下来给定一个有向图

问从1到n最多有几种路线可以使权值之和小于e

思路

显然,为了使答案最大,我们一定要使每次的权值都尽可能的小

所以这就是一个K短路问题了(在k条路的时候正好小于等于e)

单纯的K短路就是记录每个点经过的次数

如果最后一个点走过k遍就是它的K短路了

下面的很多代码是为了优化,如果想看单纯的K短路算法请看别的blog

首先SPFA先找出终点到每个点的最短距离(要先建反向图)

A_star的估价函数就是当前距离加上这个点到终点的最短距离

(很好证明吧因为这个点到终点最短最短就是上面这东西了)

然后我们可以对这个f(x)进行优先队列的优化 不知道f(x)是什么东西去看看A*算法吧

可能还是说的不是很清楚,还不懂的就直接看代码吧

#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int g,n,m,head[5005],tail[5005],ans;
double d[5005],e;
struct node{
int from,to,next;
double e;
}l[200005],lu[200005];
struct data{
int d;
double g,f;
bool operator < (const data &a) const {
if(f>a.f)return 1;return 0;
}//运算符重载堆优化
}zz,mm;
void add(int x,int y,double z)
{
g++;l[g].next=head[x],head[x]=g;
l[g].from=x,l[g].to=y,l[g].e=z;

lu[g].next=tail[y],tail[y]=g;
lu[g].from=y,lu[g].to=x,lu[g].e=z;
}//建正向图的同时建反响图
int read()
{
int z=0,f=1;
char k=getchar();
while(k<'0'||k>'9')  {if(k=='-')f=-1;k=getchar();}
while(k>='0'&&k<='9'){z=(z<<3)+(z<<1)+k-'0';k=getchar();}
return z*f;
}//读优
queue<int>p;//优化SPFA
void spfa()
{
int bj[5005]={0};
for(int i=1;i<n;i++)d[i]=0x7fffffff;
p.push(n);
while(!p.empty())
{
int u=p.front();p.pop();
for(int i=tail[u];i;i=lu[i].next)
{
int v=lu[i].to;
if(d[u]+lu[i].e<d[v])
{
d[v]=d[u]+lu[i].e;
if(!bj[v])bj[v]=1,p.push(v);
}
}
bj[u]=0;
}
}
int time[5005];//记录进入次数
priority_queue<data>q;//堆优化
void A_star(int kk)
{
zz.d=1,zz.g=0,zz.f=0;
q.push(zz);
while(!q.empty())
{
zz=q.top();q.pop();
if(zz.f>e) return;
int u=zz.d;
time[u]++;
if(u==n)
{
e-=zz.f;
if(e<=0)return;//优化
ans++;continue;
}
if(time[u]>kk) continue;//优化 因为kk次数之后的到达都不可能是答案的
for(int i=head[u];i;i=l[i].next)
{
mm.d=l[i].to,mm.g=zz.g+l[i].e,mm.f=mm.g+d[l[i].to];//A_star
q.push(mm);
}
}
}
int main()
{
n=read(),m=read(),scanf("%lf",&e);
for(int i=1;i<=m;i++)
{
int x,y;double z;
x=read(),y=read(),scanf("%lf",&z);
add(x,y,z);
}
spfa(),A_star(e/d[1]+1);
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++