bzoj1598: [Usaco2008 Mar]牛跑步

很久之前被ozyD去做妙的时候学的k短路,结果妙没做出来,k短路还忘了。。。把A*温了一下。

其实很好理解,先用spfa建出反图,然后dij,不想讲就搞个板子吧。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;

int n,m,k;

struct node
{
    int x,y,d,next;
}a[510000],b[510000];
int len1,last1[11000],len2,last2[11000]; 
void ins1(int x,int y,int d)
{
    len1++;
    a[len1].x=x;a[len1].y=y;a[len1].d=d;
    a[len1].next=last1[x];last1[x]=len1;
}
void ins2(int x,int y,int d)
{
    len2++;
    b[len2].x=x;b[len2].y=y;b[len2].d=d;
    b[len2].next=last2[x];last2[x]=len2;
}

//------------------------------------

int d[11000],list[11000];
bool v[11000];
void SPFA()
{
    memset(d,63,sizeof(d));d[1]=0;
    memset(v,false,sizeof(v));v[1]=true;
    int head=1,tail=2;list[1]=1;
    while(head!=tail)
    {
        int x=list[head];
        for(int k=last2[x];k;k=b[k].next)
        {
            int y=b[k].y;
            if(d[y]>d[x]+b[k].d)
            {
                d[y]=d[x]+b[k].d;
                if(v[y]==false)
                {
                    v[y]=true;
                    list[tail]=y;
                    tail++;if(tail==10000)tail=1;
                }
            }
        }
        v[x]=false;
        head++;if(head==10000)head=1;
    }
}

//------------spfa-------------------

struct As
{
    int f,g,v;//f==d[x]+g,用来维护优先队列 g表示出发走了多少距离,v相当于边目录的y 
    friend bool operator<(As n1,As n2)
    {
        if(n1.f==n2.f)return n1.g>n2.g;
        return n1.f>n2.f;
    }
};
priority_queue<As>Q;
void A_star()  
{  
    int cnt=0;As x,y;
    x.v=n,x.g=0,x.f=x.g+d[n];Q.push(x);
    while(Q.empty()==false)
    {
        x=Q.top();Q.pop();
        if(x.v==1)
        {
            cnt++;
            printf("%d\n",x.g);
            if(cnt==k)return ;
        }
        for(int k=last1[x.v];k;k=a[k].next)
        {
            y.v=a[k].y;
            y.g=x.g+a[k].d;
            y.f=y.g+d[y.v];
            Q.push(y);
        }

    }
    for(int i=cnt;i<k;i++)printf("-1\n");
}

//-------------dij----------------------

int main()
{
    int x,y,d;
    scanf("%d%d%d",&n,&m,&k);
    len1=0;memset(last1,0,sizeof(last1));
    len2=0;memset(last2,0,sizeof(last2));
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&d);
        ins1(x,y,d);ins2(y,x,d);
    }
    SPFA();
    A_star();
    return 0;
}
posted @ 2017-12-28 12:44  AKCqhzdy  阅读(229)  评论(0编辑  收藏  举报