• 空中楼阁 (最短路)


    空中楼阁 (最短路)

    版权声明:本篇随笔版权归作者YJSheep(www.cnblogs.com/yangyaojia)所有,转载请保留原地址!

    【问题描述】

    话说Z4阴差阳错地来到了神秘岛。不久,他们发现,这是一个由n个小岛和一个中心岛组成的群岛,群岛之间有m座桥。令他们感到惊讶的是,这些桥并不是固定不变的,经较长时间的观察,发现它们会随时间作周期性的变化(即桥的两端会不断更换)。

    立方很早就留意到远远的那个中心岛了。他发现岛的上空好像有一个很巨大的东西,但实在太远了,看不清楚。此时jakrinchose得意地从身上拿出一个超高倍数望远镜,好像很自豪的样子,因为他平时专门用来看美女的工具此时终于派得上用场了。

    “那是一间小屋!架在一棵好大好大的树上!”

    “Terrific!我们也许可以暂时在那安顿,好用来遮风避雨!”

    于是他们便决定前往中心岛上的那间空中楼阁。Z4的懒惰是出了名的,他们当然希望越早到越好,那么,你能帮帮他们吗?

    为方便计算,Z4把小岛按1..n编号,0表示中心岛。Z4一开始在编号为1的小岛上。在岛上行走的时间忽略不计,过桥的时间为1个单位。岛上的桥变化的周期为T,在nT+i(n=0,1,2,…;i=1,2,…,T)时刻岛上的桥为第i种状态,一开始的时刻为1。两个小岛间可能有多条桥相连。在任一时刻,Z4可以选择过桥,也可以原地不动。当然,如果无桥可过,Z4只能在原地等待。

    【输入格式】

    输入文件house.in的第一行包括三个整数n(1<=n<=80),m(1<=m<=10000)和T(1<=T<=10),分别表示小岛的个数,岛上桥的数量和桥改变的周期T。

        接下来分别描述第1..T种状态,每种状态有m行,每行有两个整数a, b(0<=a,b<=n),表示这种状态时小岛a和b有一条桥相连。两状态之间用一空行隔开。

    【输出格式】

    输出文件house.out仅有一个整数,表示Z4最少得花多少时间到达中心岛。如果Z4无法到达中心岛,则输出“Poor Z4!”。

    【输入样例1】

    4 5 2

    1 2

    1 3

    1 4

    2 0

    4 0

    1 3

    1 3

    2 3

    4 3

    3 0

    【输出样例1】

    解题报告

           仔细分析,这题就是一个最短路模型,不过每隔一段时间有些边会消失,有些会出现。我们可以用最短路模板,再判断是否松弛时加上一个等待的时间。即等到所走的边出现的时间。这样就可以啦。

    #include<bits/stdc++.h>
    #define Pair pair<int,int>
    #define MAXN 100+10
    #define MAXM 200010+10
    using namespace std;
    struct Edge{
        int from,next,to,dis,exi;
    }edge[MAXM];
    int n,m,num,v[MAXN],dis[MAXN],head[MAXN],t,s;
    void add(int from,int to,int dis,int exi)
    {
        edge[++num].next=head[from];
        edge[num].to=to;
        edge[num].exi=exi;
        edge[num].from=from;
        edge[num].dis=dis;
        head[from]=num;
    }
    int wait(int i,int dis)
    {
        if(dis%t+1==edge[i].exi) return 0;
        else
            for(int j=1;j<=t;j++)
                if((dis+j)%t+1==edge[i].exi) return j;
        }
    }
    void Bell()
    {
        for(int i=1;i<=n;i++) dis[i]=999999999;
        dis[s]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=num;j++)
            if(!(dis[edge[j].from]==999999999&&dis[edge[j].to]==999999999))
            {
                int der=wait(j,dis[edge[j].from]);
                if(der+dis[edge[j].from]+edge[j].dis<dis[edge[j].to])
                    dis[edge[j].to]=dis[edge[j].from]+edge[j].dis+der;
            }
        }
    }
    int main()
    {
        freopen("house.in","r",stdin);
        freopen("house.out","w",stdout);
        scanf("%d%d%d",&n,&m,&t);
        for(int i=1;i<=t;i++)
        {
            for(int j=1;j<=m;j++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                add(x+1,y+1,1,i);
                add(y+1,x+1,1,i);
            }
        }s=2;n++;
        Bell();
        if(dis[1]==999999999) printf("Poor Z4!
    ");
        else printf("%d
    ",dis[1]);
        return 0;
    }
  • 相关阅读:
    iis里不能同时启动多个站点的原因总结:
    相机200万提升到300万的软件技术插值法
    nginx与PHP的安装配置
    IIS和apache都要同时使用80端口的解决办法
    nginx安装与配置
    只写一个表单,可以达到两个表单的效果
    nginx伪静态规则
    伪静态涉及到的重复页面之属性canonical
    ckeditor与ckfinder组合配置
    上传图片的美化
  • 原文地址:https://www.cnblogs.com/yangyaojia/p/6346534.html
Copyright © 2020-2023  润新知