XiyouLinux兴趣小组免试题——level 5

来源:互联网 发布:php mvc框架有哪些 编辑:程序博客网 时间:2024/05/16 09:45

感谢出免试题过程中帮助我的各位学长以及提供思路的同学。

很荣幸成为免试题出题人之一,这次出题也算是对自己的一种磨练。第五关作为整个免试题的最后一关,主要考察点是算法的图论方面。接下来详细介绍一下第五关的通关攻略lol。

题目链接:level 5

假设你现在已经通过前四关来到了最后一关,首先映入眼帘的是一些星球的连线。

页面一

相信有点图论基础的同学此时心里会大概有个方向了吧,页面上有个提交按钮还有一个start:1 end:4的提示告诉你起始点为1目标点为4。页面上暂时没有什么其他的有效信息,好在点比较少,我们可以先一个一个试一下。

对于给定的起始点和目标点来说,我们有以下四种路径:
1:1->2->4
2:1->3->4
3:1->5->4
4:1->6->4
这四条路径权值和分别为:
1->2->4 :2 + 3 = 5
1->3->4 :3 + 4 = 7
1->5->4 :4 + 5 = 9
1->6->4 :5 + 6 = 11

我们分别尝试这四条路径,发现提交1->3->4这条路径时页面跳转了,进入了第五关的第二个页面。

页面二

好吧,我相信在看到第二个页面的时候很多同学的内心是拒绝的O。。。我的内心也是拒绝的。。。然而再怎么吐槽这个图我也是硬着头皮画的你们也得硬着头皮做。。。ORZ

clock

一开始拿到这个图可能会有些头大,会发现有个残忍的倒计时,但这个时候需要你们理清思路回顾以下上一个页面。在上一个页面中,我们选择1->3->4 这条路径后进入到这个页面,根据上面每条路径权值和的分析,我们发现1->3->4 是所有路径中权值和第二小的的路径。思考到这里,第五关的通关规则就很清楚了,需要你找到从起始点到目标点的次短路径

但是这么多星球,这么多连线,自己画出来十分的麻烦,这时我们可以延续前四关的优良传统——审查元素。

结点信息

这么明显的结点信息我想瞎子都能看到吧。。。赶紧先保存下来。

大概看了看,能够发现总共有50个点,97条边,每条边的权值为分数。
现在图信息有了,通关规则也有了,剩下的就是解题了。倒计时为30s,这意味着你肯定不能手动计算,还是乖乖谷歌下次短路算法吧。我们先假设你学会了次短路算法,假设你也写好了代码,假设你也得出了答案。。

#include <iostream>#include <string.h>#include <cstdio>#include <cstdlib>#include <cmath>#define N 205#define MAX 0x03fffffffusing namespace std;double Metrix[N][N];double dist[N];int vist[N];int path[N];struct edge{    int s,t;    double cost;}E[N];/*   void OutPath(int s,int t,int NV)//输出路径   {   for(int i=1;i<=NV;i++)   {   }   int u=s,v=t;   while(v!=s)   {   v=path[v];   }   }   */int Dijkstra(int s,int t,int NV){    int u=s,v=t;    for(int i=1;i<=NV;i++)    {        dist[i]=MAX;        vist[i]=0;    }    for(int i=1;i<=NV;i++)    {        path[i]=s;    }    dist[u]=0;    for(int i=1;i<=NV;i++)    {        double min_value = MAX;        for(int j=1;j<=NV;j++)        {            if(vist[j]==0&&dist[j]<min_value)            {                min_value=dist[j];                u=j;            }        }        vist[u]=1;        for(int j=1;j<=NV;j++)        {            if(vist[j]==0&&dist[u]+Metrix[u][j]<dist[j])            {                dist[j]=dist[u]+Metrix[u][j];                path[j]=u;            }        }    }    if(fabs(dist[t]-MAX) < 0.000001)return -1;    return 10;}void SP2th(int s,int t,int NV)//NV为节点数{    int flag=Dijkstra(s,t,NV);//求最短路    printf("%lf ", dist[t]);    if(flag==-1)    {        printf("0");    }    else    {        float min_SP=MAX;        int u=s,v=t,arcNum=0;        while(v!=u)//保存最短路到E[i]        {            E[arcNum].s=v;            E[arcNum].t=path[v];            E[arcNum].cost=Metrix[v][path[v]];            arcNum++;            v=path[v];        }        for(int i=0;i<arcNum;i++)        {   //删除E[i]            u=E[i].s;            v=E[i].t;            Metrix[u][v]=Metrix[v][u]=MAX;            flag=Dijkstra(s,t,NV);//重新计算最短路           // printf("  %lf-=-=\n", dist[t]);            if(flag==-1)            {                printf("0");            }            else            {                //OutPath(s,t,NV);                if(min_SP>dist[t])min_SP=dist[t];            }            Metrix[u][v]=Metrix[v][u]=E[i].cost;            int u = s, v = t;            while(v != u){                printf("%d->", v);                v = path[v];            }            printf("%d  %lf\n",s, dist[t]);        }        printf("%lf",min_SP);    }}int main(int argc, char * argv[]){    int m,n;//n为节点数,m为边数    int ss = 0;    int tt = 0;    ss= atoi(argv[1]);    tt = atoi(argv[2]);    freopen("./CASE.txt", "r", stdin);    cin >> n >> m;    int s,t;    int aa, bb;    double c = 0.0;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if(i==j)            {                Metrix[i][j]=MAX;            }            else            {                Metrix[i][j]=MAX;                Metrix[j][i]=MAX;            }        }    }    for(int i=0;i<m;i++)//每条路的代价    {        cin >> s >> t >> aa >> bb;        c = aa /(bb * 1.0);        if(c<=Metrix[t][s])        {            Metrix[s][t]=Metrix[t][s]=c;        }    }    SP2th(ss,tt,n);//<span style="font-family: Arial, Helvetica, sans-serif;">//求s->t的次短路</span>    return 0;}

提交

30秒的时间真的是有点紧,不过如果你是用程序的话还是可以来得及的,我们提交下试试

结束

看样子是过咯~

结束的话:
通关只是目的之一,第五关作为最后一关并不是挡住所有做题的人才高兴,更重要的是希望大家能够在做题的过程中学到有用的知识,如果想要学习次短路算法,建议从学习最短路算法起步。

0 0
原创粉丝点击