• 图的第k短路


    【问题描述】

    给你一个有向图,求从1到n的第k短路。
    【解法】
    SPFA+A*搜索。
    1 A*算法
    A*算法在人工智能中是一种典型的启发式搜索算法,启发中的估价是用估价函数表示的:
    h(n)=f(n)+g(n)
    其中f(n)是节点n的估价函数,g(n)表示实际状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。另外定义h'(n)为n到目标节点最佳路径的实际值。如果h'(n)≥h(n)则如果存在从初始状态走到目标状态的最小代价的解,那么用该估价函数搜索的算法就叫A*算法。
    2 第K最短路的算法
    我们设源点为s,终点为t,我们设状态f(i)的g(i)为从s走到节点i的实际距离,h(i)为从节点i到t的最短距离,从而满足A*算法的要求,当第K次走到f(n-1)时表示此时的g(n-1)为第K最短路长度。
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<ctime>
      7 #include<algorithm>
      8 #include<queue>
      9 #define MAXN 20100
     10 #define INF 1000100000
     11 #define pii pair<int,int> 
     12 using namespace std;
     13 struct node{int y,next,v;}e1[MAXN],e2[MAXN];
     14 struct node2
     15 {
     16     int f,g,id;    
     17     friend bool operator < (node2 a,node2 b)
     18     {
     19         return a.f>b.f;
     20     }
     21 };
     22 int n,m,k,len1,len2,Link1[MAXN],Link2[MAXN],dis[MAXN],vis[MAXN],tim[MAXN],ans[MAXN];
     23 priority_queue<node2>Q;
     24 inline int read()
     25 {
     26     int x=0,f=1;  char ch=getchar();
     27     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
     28     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
     29     return x*f;
     30 }
     31 void insert(int xx,int yy,int vv)
     32 {
     33     e1[++len1].next=Link1[xx];
     34     Link1[xx]=len1;
     35     e1[len1].y=yy;
     36     e1[len1].v=vv;              
     37     e2[++len2].next=Link2[yy];
     38     Link2[yy]=len2;
     39     e2[len2].y=xx;
     40     e2[len2].v=vv;              
     41 }
     42 void SPFA()
     43 {
     44     priority_queue<int,vector< int >,greater< int > >q;
     45     memset(dis,50,sizeof(dis));
     46     dis[1]=0,vis[1]=1,q.push(1);
     47     while(!q.empty())
     48     {
     49         int tn=q.top();
     50         vis[tn]=0;
     51         q.pop();
     52         for(int i=Link2[tn];i;i=e2[i].next)
     53         {
     54             int tmp=e2[i].y;
     55             if(dis[tmp]>dis[tn]+e2[i].v)
     56             {
     57                 dis[tmp]=dis[tn]+e2[i].v;
     58                 if(!vis[tmp])
     59                 {
     60                     vis[tmp]=1;
     61                     q.push(tmp);
     62                 }
     63             }
     64         }
     65     }
     66 }
     67 void Astar()
     68 {
     69     if(dis[n]==INF)  return;
     70     node2 temp;  temp.g=0,temp.f=dis[n],temp.id=n;
     71     Q.push(temp);
     72     while(!Q.empty())
     73     {
     74         temp=Q.top(); Q.pop();
     75         if(temp.id==1)  {ans[++ans[0]]=temp.f;  if(ans[0]>k)  return;}  
     76         for(int i=Link1[temp.id];i;i=e1[i].next)
     77         {
     78             node2 opt;
     79             opt.g=temp.g+e1[i].v;
     80             opt.f=opt.g+dis[e1[i].y];
     81             opt.id=e1[i].y;
     82             Q.push(opt);
     83         }
     84     }
     85 }
     86 int main()
     87 {
     88     n=read();  m=read();  k=read();
     89     for(int i=1;i<=m;i++)
     90     {
     91         int x=read(),y=read(),v=read();
     92         insert(x,y,v);
     93     }
     94     SPFA();
     95     Astar();
     96     for(int i=1;i<=k;i++)
     97     {
     98         if(!ans[i])  printf("-1
    ");
     99         else printf("%d
    ",ans[i]);
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    IBM Lotus网站荟萃
    Lotus 深入浅出系列——前言(二)IBM Lotus开发人员的几个境界
    在IIS上配置和测试Perl脚本
    网站推广
    iTOP开发板MiniLinuxC程序调用shell命令
    iTOP4412开发板_驱动_adc驱动升级和测试例程
    最近想入手树莓派3来学习编程同学没有选择4412开发板吗?
    iTOP4412开发板串口转接小板的使用文档
    学习嵌入式4412开发板手把手配套视频_2000人群组在线交流
    电子医疗设备创新研发应该用i.MX6Q开发板吗?为医疗设备提供解决方案
  • 原文地址:https://www.cnblogs.com/chty/p/5827549.html
Copyright © 2020-2023  润新知