手写堆优化Dijkstra

https://www.luogu.com.cn/problem/P4779

\(Code:\)

#include<bits/stdc++.h>
#define N 100005
#define M 200005
#define INF 2000000000000000
using namespace std;
int head[N],d1[M],d2[M],nxt[M];
int n,m,s,x,y,z,tot;
long long dis[N];
struct Heap
{
    int cnt=0;
    int id[N];
    long long a[N];
    int pos[N];
    void clear()
    {
        cnt=0;
    }
    void push(int x,long long y)
    {
        cnt++;
        a[cnt]=x,id[cnt]=y,pos[y]=cnt;
        int t=cnt;
        while (t!=1 && a[t]<a[t >> 1])
            swap(pos[id[t]],pos[id[t >> 1]]),swap(a[t],a[t >> 1]),swap(id[t],id[t >> 1]),t >>=1;
    }
    int top()//返回堆顶的id
    {
        return id[1];
    }
    bool empty()
    {
        return cnt==0;
    }
    void pop()
    {
        swap(pos[id[1]],pos[id[cnt]]),swap(a[1],a[cnt]),swap(id[1],id[cnt]);
        pos[id[cnt]]=0;
        cnt--;
        int t=1;
        while ((t << 1)<=cnt && a[t]>a[t << 1] || (t << 1)<cnt && a[t]>a[t << 1 | 1])
            if ((t << 1 | 1)>cnt || a[t << 1]<a[t << 1 | 1])
                swap(pos[id[t]],pos[id[t << 1]]),swap(a[t],a[t << 1]),swap(id[t],id[t << 1]),t <<=1; else
                swap(pos[id[t]],pos[id[t << 1 | 1]]),swap(a[t],a[t << 1 | 1]),swap(id[t],id[t << 1 | 1]),t=t << 1 | 1;
    }
    void modify(int x,int y)
    {
        a[x]=y;
        int t=x;
        while (t!=1 && a[t]<a[t >> 1])
            swap(pos[id[t]],pos[id[t >> 1]]),swap(a[t],a[t >> 1]),swap(id[t],id[t >> 1]),t >>=1;
    }
}q;
void add(int x,int y,int z)
{
	tot++;
	d1[tot]=y;
	d2[tot]=z;
	nxt[tot]=head[x];
	head[x]=tot;
}
int main() 
{
	scanf("%d%d%d",&n,&m,&s);
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
	}
	for (int i=1;i<=n;i++)
		dis[i]=INF;
	dis[s]=0;
	q.push(dis[s],s);
	while (!q.empty())
	{
		int u=q.top();
		q.pop();
		for (int i=head[u];i;i=nxt[i])
		{
			int v=d1[i];
			int cost=d2[i];
			if (dis[u]+cost<dis[v])
			{
				dis[v]=dis[u]+cost;
				if (!q.pos[v])
                    q.push(dis[v],v); else
                    q.modify(q.pos[v],dis[v]);
			}
		}
	}
	for (int i=1;i<=n;i++)
		printf("%lld ",dis[i]);
	putchar('\n');
	return 0;
}
posted @ 2020-10-12 16:57  GK0328  阅读(123)  评论(0编辑  收藏  举报