吴昊品游戏核心算法 Round 16 —— 吴昊教你玩口袋妖怪 第五弹 火箭队的秘密基地...

 

  谁时拯救这个世界的英雄?在二次元世界中,两个最有爱的反派角色,莫过于火箭队的这两员了。他们为了维护这个宇宙的和平而存在,尽管每次确实有失利了,但是,却给我们留下了深刻的印象。那么,在三次元世界中,谁是拯救这个世界的英雄呢?我认为,此人乃是阿桑奇。

  好了,这里不说到底是谁在拯救这个世界了,不过,这一弹确实和火箭队有关。

 

  如图所示,在云雾缭绕的氛围中有若干个黑色的地洞,而位于地洞P的那个房间坐着的人,就是板木老人了。我们这里以N点作为起始点,每进入一个地洞,则会有一种对应的转移(当然,这种转移可以是双向的,对应为无向图),我们的目的是到达P点,当然,我们可以尝试很多方式,也愿意避免碰到火箭队的内部队员的挑战。我们如何可以方便地到达P点呢?(这里的方便指明了两点,第一,转移的次数可以尽可能少,第二,尽量可以避免遇到前来挑战的人),明确了这两点之后,改问题转化为了一个带权重(widget的值应该就是挑战者的能力了)的最短路问题了。

 

  这又是一个火箭队的秘密基地,不过,这里的情况貌似比之前的要简单许多,多了几道门,少了几个状态转移区域。我们可以采用同样的方式,来利用AI,用最短的转移次数到达我们所需要到达的目标点。我们将每一个转移区域按照序号分别标注,因为挑战者的干扰,这里对每一条边考虑一个权重(这里的权重是正值,因为,即使是没有火箭队的内部人员存在,我们的权重也是大于等于1的(这一步算你转移耗费的能量,然后,以此作为衡量标准来衡量那些脑残的火箭队挑战者的权重)),考虑到权重的恒正,我们可以利用Dijkstra算法来计算最短路径了!

 

  Dijkstra奥义:

  Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。

 

  步骤如下:

  STEP 1: 初使时令 S={V0},T={其余顶点}T中顶点对应的距离值若存在<V0,Vi>d(V0,Vi)<V0,Vi>弧上的权值若不存在<V0,Vi>d(V0,Vi)

  STEP 2: T中选取一个其距离值为最小的顶点W且不在S中,加入S

  STEP 3: 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0Vi的距离值缩短,则修改此距离值重复上述步骤23,直到S中包含所有顶点,即W=Vi为止

 

  Input:每组数据第一行包含两个正整数NM(0<N<200,0<M<1000),分别代表现有转移区域的数目和转移的路径(这里的边是给定的)。接下来是M行转移路径信息。每一行有三个整数A,B,X,表示转移区域A和转移区域B之间的权重(这个概念在之前已经解释过了)。再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。

  Output:计算耗费能量的最小值,如果不能到达的话,输出-1

 

  Solve:

 这里的时间复杂度是ON^2,还可以利用比较好的数据结构将该算法进行进一步的优化,Dijkstra算法最好的复杂度也是O(NlogN+E),用Fibonacci堆来实现优先队列就可以达到该复杂度。

 

  1  // C++和C的输入输出流通用
  2 
  3  #include <iostream>
  4 
  5  #include <cstdio>
  6 
  7   using  namespace std;
  8 
  9  
 10 
 11   #define  Max 210
 12 
 13  
 14 
 15   // 设置一个极大的常数,INTMAX,由于INT本身是32位的,所以,这个INTMAX已经非常大了
 16 
 17   const  int INTMAX= 1<< 30;
 18 
 19   int p[Max][Max];
 20 
 21   int dist[Max],s[Max];
 22 
 23   int n,m,v;
 24 
 25  
 26 
 27   // 在初始化的时候,将所有的边设为最大值
 28 
 29   void init()
 30 
 31  {
 32 
 33     for ( int i= 0;i<n;i++)
 34 
 35       for ( int j= 0;j<n;j++)
 36 
 37        p[i][j]=INTMAX;
 38 
 39  }
 40 
 41  
 42 
 43   void dijkstra()
 44 
 45  {
 46 
 47     int i,w,j,min,u;
 48 
 49     for (i= 0;i<n;i++)
 50 
 51    {
 52 
 53       // 这里说明起始点到每一条边的距离
 54 
 55      dist[i]=p[v][i];
 56 
 57      s[i]= 0;
 58 
 59    }
 60 
 61    s[v]= 1;
 62 
 63     // 自己到自己是没有长度的
 64 
 65    dist[v]= 0;
 66 
 67     for (i= 0;i<n;i++)
 68 
 69    {
 70 
 71      min=INTMAX;
 72 
 73      u=v;
 74 
 75       // 找到到某一点(最开始是起始点)的最短路径
 76 
 77       for (j= 0;j<n;j++)
 78 
 79         if (!s[j]&&dist[j]<min)
 80 
 81          min=dist[u=j];
 82 
 83      s[u]= 1;
 84 
 85       // 找到一条可以代替的最短路
 86 
 87       for (w= 0;w<n;w++)
 88 
 89         if (!s[w]&&dist[u]+p[u][w]<dist[w]&&p[u][w]<INTMAX)
 90 
 91          dist[w]=dist[u]+p[u][w];
 92 
 93    }
 94 
 95  }
 96 
 97  
 98 
 99   int main()
100 
101  {
102 
103     int i,j,a,b,c,k;
104 
105     // 开始,先输入起点和对应的边
106 
107     while (cin>>n>>m)
108 
109    {
110 
111       // 初始化各条边
112 
113      init();
114 
115       for (i= 0;i<m;i++)
116 
117      {
118 
119        scanf( " %d%d%d ",&a,&b,&c);
120 
121         // 这里注意到边是双向的,我们既可以转移过去,也可以转移回来
122 
123         if (c<p[a][b])
124 
125          p[a][b]=p[b][a]=c;       
126 
127      }
128 
129       // 这里输入起始点和终止点
130 
131      cin>>v>>k;
132 
133      dijkstra();
134 
135       // 这里说明路径找不到
136 
137       if (dist[k]==INTMAX) cout<< " -1 "<<endl;        
138 
139       else cout<<dist[k]<<endl;   
140 
141    }
142 
143     return  0;
144 
145  }

转载于:https://www.cnblogs.com/tuanzang/archive/2013/04/01/2992923.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 吴昊 20200722041 题量: 27 满分:100.0 截止日期:2023-05-23 12:00 吴昊 39' 57'' 数据采集与网络爬虫第一次阶段测试 返回 26 交卷 已知hello.html文件的内容如下。 <html> <body> <div> <ul> <li class="item-0"><a href="link1.html">first item </a></li> <li class="item-1"><a href="link2.html">second item </a></li> <li class="item-inactive"><a href="link3.html">third item </a></li> <li class="item-0"><a href="link4.html">fourth item </a></li> <li class="item-0"><a href="link5.html">fifth item </a></li> </ul></div></body></html> 请使用lxml库分别按照如下要求查找hello.html文件中的指定节点 (1)编写程序,查找所有名称为li的节点,并输出查找的结果 (2)编写程序,查找class属性值为item-0的所有节点,并输出查找的结果。 (3)编写程序,查找<li>下href属性值为link1.html的名为a的子节点,并输出查找的结果
05-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值