• 【FZYZOJ】下片 题解(最短路+超级源点)


    题目描述

    为了提高服务器的耐受能力,很多流量大的网站都会架设多台服务器,而互联网的路由能找到线路最短的一台服务器。 现在UOI想要下片,他有好多台电脑,又有好多服务器可以提供下载。UOI将给你一个网络图,告诉你点点之间的线路长度,问最短的线路长是多少,以及选择的那台用来下载的电脑和被选的服务器的编号。 如果有多台电脑/服务器之间连线都是最短线路,输出电脑编号最小的;如果还有多种选择,输出服务器编号最小的。

    输入格式

    第一行n,m,表示总格有n个点,m条网络连线 接下来m行,表示每条网络连线所连接的A、B点和线的长度。 接下来一个数T1,表示UOI有多少台电脑。 下一行T1个数,表示UOI每台电脑的编号。 接下来一个数T2,表示有多少台服务器。 下一行T2个数,表示每台服务器编号。

    输出格式

    三个数,分别是线路长度,UOI下载用的电脑,提供片的下载源

    -------------------------------------------------------------------------------------------------------------------------

    题意转化:给你一些源点和一些汇点,求一条连接源点和汇点的路径并且使得这条路径的长度最小。

    使用n次spfa显然会TLE。这时候我们要引入一个概念:超级源点。意思是引入一个0号点,能连接所有源点,并且不影响原图,即长度为0。这样跑1次spfa就够。此题还要求输出源点和汇点,我们开一个pre数组,记录每个点的前驱即可(前驱指的是从哪个源点可以到达那里)。

    代码中稍稍做了一点修改,本身思路与其相符。

    #include<bits/stdc++.h>
    using namespace std;
    queue<int> q;
    struct node
    {
        int to,dis;
    };
    vector<node> v[100005];
    int n,m,t1,t2,a[100005],vis[100005],pre[100005];
    long long ans=9223372036854775807,dis[100005];
    int ans1,ans2;
    int main()
    {
        memset(dis,0x3f,sizeof(dis));
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
        {
            int u,to,d;
            scanf("%d%d%d",&u,&to,&d);
            v[u].push_back((node){to,d});
            v[to].push_back((node){u,d});
        }
        scanf("%d",&t1);
        for (int i=1;i<=t1;i++) scanf("%d",&a[i]);
        sort(a+1,a+t1+1);
        scanf("%d",&t2);
        int t;
        for (int i=1;i<=t2;i++) scanf("%d",&t),pre[t]=t,vis[t]=1,dis[t]=0,q.push(t);
        while(!q.empty())
        {
            int now=q.front();q.pop();vis[now]=0;
            for (int i=0;i<v[now].size();i++)
            {
                int to=v[now][i].to;
                if (dis[to]>dis[now]+v[now][i].dis)
                {
                    pre[to]=pre[now];
                    dis[to]=dis[now]+v[now][i].dis;
                    if (!vis[to]) vis[to]=1,q.push(to);
                 } 
            }
        }
        for (int i=1;i<=t1;i++)
            if (ans>dis[a[i]]) ans=dis[a[i]],ans1=a[i];
        printf("%ld %d %d",ans,ans1,pre[ans1]);
        return 0;
    }
  • 相关阅读:
    VS中编码格式的问题(待总结)
    第一次搭建Eureka服务器的虐心之路
    Eureka相关
    【移动开发】SparseArray替代HashMap
    【移动开发】plurals
    皮尔森相似度计算举例(R语言)
    据说,年薪百万的程序员,都是这么开悟的
    RDD:基于内存的集群计算容错抽象
    使用IDEA运行Spark程序
    scala for spark
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/12454307.html
Copyright © 2020-2023  润新知