第 K 最短路 问题

在这求第  k 短路用的是,A*+dij 所谓的A* 是一种启发式搜索,他给搜索选定一定的方向,避免了,无谓的搜索,如何来确定搜索的顺序?..也就是用一个值来表示这个值为f[x]..每次搜索取f[x]最小的拓展...那么这个f[x]=h[x]+g[x]其中这个h[x]就是当前搜索时的代价..如求K段路这个就是前一个点的h[x']+边的长度...而g[x]是一个估价函数..估价函数要小于是对当前点到目标的代价的估计..这个估计必须小于等于实际值~~否则会出错...A*的关键也就是构造g[x]..,我们的dij 算法。最短路是,就是一种 A* 搜索,其中 g[x]=0;

 

而这里要说的求K短路一种方法..就是用BFS+A*来搜索的过程...g[x]的设定为到这个点到目标点的最短路(这个可以用dij 一次求出) 径...显然其实小于等于实际值的...h[x]就是搜索到这个点的代价(及走过的路程)..用一个优先队列来做..每次取出h[x]+g[x]最小的点来拓展...拓展 也就是通过这点来更新其能直接经过一条边到达的点..这里做好一个新点就丢进优先队列里去..反正总会从对首弹出h[x]+g[x]最小的点..

 

首先,我们在放优先队列的是这样的节点,他包括,从原点 到达本节点 的路径长度  len ,然后我们在优先列里,按照 len +dis[i] (dis 到达终点的最最短路)的最小,优先级 排队,

那么当我们第一次搜索到 E 点时,这时肯定是 最短路径,第二次取出的,就是第二短路,以此类推,

struct cnode
{
    int u;
    int len;
    cnode (int uu,int ww):u(uu),len(ww){}
    friend bool operator < (cnode a,cnode b)
    {
        return a.len+dis[a.u]>b.len+dis[b.u];
    }
};

  我们从一个点,如何扩展的下一个点呢,就是,将与相连的点 ,入队列,( 这样 就会走重复的边 )

       队列里面的节点就是,原点 经过 len 的路经 所到达的状态

 

 1 int A_star(int s)
 2 {
 3     int i;
 4     if(dis[s]==inf)return -1;//这个一定要有,若s到t不连通的话,下面会 死循环
 5     priority_queue<cnode>que;
 6 
 7     CL(tol,0);
 8     que.push(cnode(s,0));
 9     while(!que.empty())
10     {
11         cnode a=que.top();que.pop();
12         int u=a.u;
13         int len=a.len;
14         tol[u]++;
15         if(tol[t]==k)return len;
16 
17         for(i=0;i<g[u].size();i++)
18         {
19             node b=g[u][i];
20             int v=b.u;
21             que.push(cnode(v,len+b.w));
22         }
23 
24     }
25     return -1;
26 }

那要是本身就不存在K短路呢??那就是e拓展不到K但是其他点很有可能一直打圈圈无限下去...这里就要用个条件来判断一 下...首先在找某个点作为优先队列头出现了几次就用了一个计数器times[]..所求的点times[e]==k就代表得到了解..如果当前想拓展的 点times[]>k就没必要拓展了..因为这个点已经是求到k+1短路了..从这个点继续往下搜肯定得到的是大于等于k+1短路的路径...就像 1->2有3条路..2->3有2条路..那1->3有6条路的概念差不多..没必要对其进行拓展了..

 

注意 :

  若是 有向边时,我们求 到终点的最短距离时,要将边 反向

 

poj 2449   Remmarguts' Date   (有向边)

http://poj.org/problem?id=2449

求任意两点的第 k 短路  

View Code
  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<set>
  8 #include<map>
  9 #define Min(a,b)  a>b?b:a
 10 #define Max(a,b)  a>b?a:b
 11 #define CL(a,num)  memset(a,num,sizeof(a));
 12 #define inf 9999999
 13 #define maxn 1030
 14 #define eps  1e-6
 15 using namespace std;
 16 
 17 struct node
 18 {
 19     int u;
 20     int w;
 21     node (int uu,int ww):u(uu),w(ww){}
 22 };
 23 vector<node>g[maxn],rg[maxn];
 24 int dis[maxn],vis[maxn],tol[maxn];
 25 struct cnode
 26 {
 27     int u;
 28     int len;
 29     cnode (int uu,int ww):u(uu),len(ww){}
 30     friend bool operator < (cnode a,cnode b)
 31     {
 32         return a.len+dis[a.u]>b.len+dis[b.u];
 33     }
 34 };
 35 int n,m,s,t,k;
 36 void spfa(int s)
 37 {
 38     int i;
 39     for(i=0;i<=n;i++)
 40     {
 41         dis[i]=inf;
 42         vis[i]=0;
 43     }
 44     dis[s]=0;
 45     queue<int>que;
 46     que.push(s);
 47     while(!que.empty())
 48     {
 49         int u=que.front();que.pop();
 50         vis[u]=0;
 51         for(i=0;i<rg[u].size();i++)
 52         {
 53             node b=rg[u][i];
 54             int v=b.u;
 55             if(dis[v]>dis[u]+b.w)
 56             {
 57                 dis[v]=dis[u]+b.w;
 58                 if(!vis[v])
 59                 {
 60                     vis[v]=1;
 61                     que.push(v);
 62                 }
 63             }
 64         }
 65     }
 66 
 67 }
 68 int A_star(int s)
 69 {
 70     int i;
 71     if(dis[s]==inf)return -1;//
 72     priority_queue<cnode>que;
 73 
 74     CL(tol,0);
 75     que.push(cnode(s,0));
 76     while(!que.empty())
 77     {
 78         cnode a=que.top();que.pop();
 79         int u=a.u;
 80         int len=a.len;
 81         tol[u]++;
 82         if(tol[t]==k)return len;
 83 
 84         for(i=0;i<g[u].size();i++)
 85         {
 86             node b=g[u][i];
 87             int v=b.u;
 88             que.push(cnode(v,len+b.w));
 89         }
 90 
 91     }
 92     return -1;
 93 }
 94 int main()
 95 {
 96     int i,x,y,z;
 97     while(scanf("%d%d",&n,&m)!=EOF)
 98     {
 99         for(i=0;i<=n;i++)g[i].clear();
100         for(i=0;i<m;i++)
101         {
102             scanf("%d%d%d",&x,&y,&z);
103             g[x].push_back(node(y,z));
104             rg[y].push_back(node(x,z));
105         }
106         scanf("%d%d%d",&s,&t,&k);
107         if(s==t)k++;
108         spfa(t);
109        int ans=A_star(s);
110        cout<<ans<<endl;
111 
112 
113 
114     }
115 }

 

poj 3255  Roadblocks

求 1到 n 的次短路

View Code
  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<set>
  8 #include<map>
  9 #define Min(a,b)  a>b?b:a
 10 #define Max(a,b)  a>b?a:b
 11 #define CL(a,num)  memset(a,num,sizeof(a));
 12 #define inf 9999999
 13 #define maxn 5030
 14 #define eps  1e-6
 15 using namespace std;
 16 int n,k,m;
 17 int dis[maxn],tol[maxn],vis[maxn];
 18 struct node
 19 {
 20     int u;
 21     int w;
 22     node (int uu,int ww):u(uu),w(ww){}
 23 };
 24 vector<node>g[maxn];
 25 struct anode
 26 {
 27     int  u;
 28     int len;
 29 
 30     anode (int uu ,int w):u(uu),len(w){}
 31 
 32     friend bool operator < (anode a, anode b)
 33     {
 34         return a.len+dis[a.u]>b.len+dis[b.u];
 35     }
 36 };
 37 void SPFA(int x)
 38 {
 39     int i;
 40     for(i=0;i<=n;i++)
 41     {
 42         dis[i]=inf;
 43         vis[i]=0;
 44     }
 45 
 46     dis[n]=0;
 47     queue< int >que;
 48     que.push(n);
 49     vis[n]=1;
 50     while(!que.empty())
 51     {
 52         int u = que.front();que.pop();
 53 
 54 
 55            vis[u]=0;
 56            for(i=0;i<g[u].size();i++)
 57            {
 58                node b=g[u][i];
 59                int v=b.u;
 60                if(dis[v]>dis[u]+b.w)
 61                {
 62                    dis[v]=dis[u]+b.w;
 63 
 64                    if(!vis[v])
 65                    {
 66                        vis[v]=1;
 67                        que.push(v);
 68 
 69                    }
 70                }
 71            }
 72     }
 73 
 74     //for(i=1;i<=n;i++)printf("%d ",dis[i]);
 75     //printf("\n");
 76 
 77 
 78 }
 79 int  A_star(int s)
 80 {
 81      int i;
 82 
 83     if(dis[s]==inf)return -1;
 84     priority_queue<anode>que;
 85 
 86     CL(tol,0);
 87     que.push(anode(1,0));
 88     while(!que.empty())
 89     {
 90 
 91         anode a=que.top();que.pop();
 92         int u=a.u;
 93         int len=a.len;
 94         tol[u]++;
 95         if(tol[n]==k)return len;
 96         for(i=0;i<g[u].size();i++)
 97         {
 98             node b=g[u][i];
 99             int v=b.u;
100             que.push(anode(v,len+b.w));
101 
102 
103         }
104     }
105     return -1;
106 
107 }
108 int main()
109 {
110     int i,x,y,z;
111     while(scanf("%d%d",&n,&m)!=EOF)
112     {
113         k=2;
114         for(i=0;i<m;i++)
115         {
116             scanf("%d%d%d",&x,&y,&z);
117             g[x].push_back(node(y,z));
118             g[y].push_back(node(x,z));
119 
120         }
121         SPFA(n);
122         int ans=A_star(1);
123         cout<<ans<<endl;
124 
125     }
126 }
posted @ 2012-07-31 09:27  Szz  阅读(1660)  评论(0编辑  收藏  举报