poj2449Remmarguts' Date

来源:互联网 发布:网络技术员 编辑:程序博客网 时间:2024/05/22 14:08

题目大意:

有向图求两个点之间的K短路;

解题思路

穷举所有路径。。。。。。用A*+spfa+链式前向星

什么是A*

可以理解为一个优先级的函数。f (x) = g(x) + h(x)  g(x)===从起点到X的距离, h(X) 从终点到x的距离

至于什么是向前星,其实就是邻接表的变形,避免动态开辟内存而已。


/***@fenghui 启发式搜索+spfa**/#include<stdio.h>#include<string.h>#include<vector>#include<queue>#define inf 1<<31-1#define N 1011using namespace std;int dis[N],head1[N],head2[N];//前向星struct node1{   int v,w,next;};node1 edg1[N*100],edg2[N*100];bool in_q[N];struct node2{   int v,f,g;   bool operator <(const node2 &x)const   {       if(x.f==f) return x.g<g;          return x.f<f;   }};int h;//向前星void initi(int n){    int i;    for(i=0;i<=n;i++)    {        dis[i]=inf;        head1[i]=-1;        head2[i]=-1;        in_q[i]=false;    }    h=0;}void add(int u,int v,int w){    edg1[h].v=v;    edg1[h].w=w;    edg1[h].next=head1[u];    head1[u]=h;    edg2[h].v=u;    edg2[h].w=w;    edg2[h].next=head2[v];    head2[v]=h;    ++h;}//struct cmp{//  bool operator()(const int x,const int y)//  {//    return dis[x]>dis[y];//  }//};void spfa(int st,int ed){//    priority_queue<int,vector<int>,cmp>q;    queue<int>q;    q.push(st);    in_q[st]=true;    dis[st]=0;    int si,ui,mdis,i;    while(!q.empty())    {//        si=q.top();        si=q.front();        q.pop();        in_q[si]=false;        for(i=head2[si];i!=-1;i=edg2[i].next)        {            ui=edg2[i].v;            mdis=dis[si]+edg2[i].w;            if(mdis<dis[ui]){                dis[ui]=mdis;                if(!in_q[ui]){                    q.push(ui);                    in_q[ui]=true;                }            }        }    }//    printf("%d \n",dis[ed]);}//启发式搜索。f(x) = g(x)到当前点的距离 + h(x)当前点到终点的距离。int astar(int st,int ed,int k){    if(st==ed)          k++;    if(dis[st]==inf)//反向不连通,正向也必然不连通            return -1;    priority_queue<node2>q;//二级排序f,g从小到大!!!    node2 temp,ui;    temp.v=st;    temp.g=0;    temp.f=temp.g+dis[temp.v];    q.push(temp);    int cnt=0,i;    while(!q.empty())    {        temp=q.top();        q.pop();        if(temp.v==ed)                cnt++;        if(cnt==k)              return temp.g;        for(i=head1[temp.v];i!=-1;i=edg1[i].next)        {            ui.v=edg1[i].v;            ui.g=temp.g+edg1[i].w;            ui.f=ui.g+dis[ui.v];            q.push(ui);        }    }    //不存在K短路    return -1;}int main(){    int n,m,i,ans;    int st,ed,k;    int a,b,d;    while(scanf("%d%d",&n,&m)!=EOF)    {        initi(n);        for(i=0;i<m;i++)        {            scanf("%d%d%d",&a,&b,&d);            add(a,b,d);        }        scanf("%d%d%d",&st,&ed,&k);        spfa(ed,st);        ans=astar(st,ed,k);        printf("%d\n",ans);    }    return 0;}



0 0