您的位置:首页 > 其它

BZOJ 1975 [Sdoi2010]魔法猪学院 - k短路(手写堆)

2017-09-22 10:20 369 查看
大概就是一道k短路的裸题,然后恶心得要手写堆,学习了一下写法,发现好简单233

注意就是当搜索到终点时不可continue,终点存在自环,可以从终点出发再次搜到终点。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
#define INF 1e20

using namespace std;

const int maxn=5005;
const int maxm=200005;

int n,m,cnt,fcnt,ans,top;
int head[maxn],fhead[maxn];
bool in[maxn];
double sum,dist[maxn];

struct edge
{
int to,next;
double val;
}e[maxm],fe[maxm];

struct node
{
int to;
double val;
bool operator < (const node &a)const
{
return dist[to]+val<dist[a.to]+a.val;
}
bool operator > (const node &a)const
{
return dist[to]+val>dist[a.to]+a.val;
}
}q[maxm<<3];

void insert(int a,int b,double val)
{
e[++cnt].to=b;e[cnt].next=head[a];e[cnt].val=val;head[a]=cnt;
}
void finsert(int a,int b,double val)
{
fe[++fcnt].to=b;fe[fcnt].next=fhead[a];fe[fcnt].val=val;fhead[a]=fcnt;
}
void push(node x)
{
q[++top]=x;
int t=top;
while(t>1)
{
if(q[t]<q[t>>1])
{
swap(q[t],q[t>>1]);
t>>=1;
}
else break;
}
}
void pop()
{
q[1]=q[top--];
int x=2;
while(x<=top)
{
if(q[x]>q[x+1]&&x+1<=top)x++;
if(q[x]<q[x>>1])
{
swap(q[x],q[x>>1]);
x<<=1;
}
else break;
}
}
node front()
{
return q[1];
}
void spfa()
{
for(int i=1;i<=n;i++)dist[i]=INF;
dist[1]=0;
in[1]=true;
queue<int>qu;
qu.push(1);
while(!qu.empty())
{
int u=qu.front();
qu.pop();
in[u]=false;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dist[v]>dist[u]+e[i].val)
{
dist[v]=dist[u]+e[i].val;
if(!in[v])qu.push(v),in[v]=true;
}
}
}
}
void kth_path()
{
push((node){n,0});
while(top)
{
int u=front().to;
double now=front().val;
pop();
if(u==1)
{
if(sum<now)break;
sum-=now;
ans++;
//continue;
}
for(int i=fhead[u];i;i=fe[i].next)
{
int v=fe[i].to;
push((node){v,now+fe[i].val});
}
}

}
int main()
{
scanf("%d%d%lf",&n,&m,&sum);
for(int i=1;i<=m;i++)
{
int a,b;double val;
scanf("%d%d%lf",&a,&b,&val);
insert(a,b,val);
finsert(b,a,val);
}
spfa();
kth_path();
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: