zoukankan      html  css  js  c++  java
  • 九度OJ 1100:最短路径 (最短路径)

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:4185

    解决:619

    题目描述:

    N个城市,标号从0到N-1,M条道路,第K条道路(K从0开始)的长度为2^K,求编号为0的城市到其他城市的最短距离

    输入:

    第一行两个正整数N(2<=N<=100)M(M<=500),表示有N个城市,M条道路
    接下来M行两个整数,表示相连的两个城市的编号

    输出:

    N-1行,表示0号城市到其他城市的最短路,如果无法到达,输出-1,数值太大的以MOD 100000 的结果输出。

    样例输入:
    4 4
    1 2
    2 3
    1 3
    0 1
    样例输出:
    8
    9
    11
    来源:
    2010年上海交通大学计算机研究生机试真题

    思路:

    此题的路径长度很特殊,不能用普通的数值来表示。可以用数组或字符串的方式来表示路径长度,同时定义相应的大整数运算。

    但由于路径长度的特殊性,更简单的办法是求最小生成树,求的过程中顺便求得最短路径。

    我开始用的第一种方法,需要考虑的细节较多,出错了几次,后来用第二种方法AC的。


    代码:

    #include <stdio.h>
    #include <stdlib.h>
     
    int rank[100] ;//记录每个树的深度
    int pre[100];//记录每个点的父节点
    int d[100][100];//记录各对间的距离
     
    void initSet(int n)//初始化,将每个点的父节点设为自己,深度为1
    {
        int i;
        for(i=0; i<n; i++)
        {
            rank[i] = 1;
            pre[i] = i;
            d[i][i] = 0;
        }
    }
     
    int findSet(int x)//找到每个点的父节点,并将这个点的父节点设置为数的根节点
    {
        if(x != pre[x])
            pre[x] = findSet(pre[x]);
        return pre[x];
    }
     
    void unionSet(int a, int b)//合并树,
    {
        int x = findSet(a);
        int y = findSet(b);
        if(x == y)//如果两个节点的父节点(树的根节点)是同一个,无需合并,直接跳过
            return;
        if(rank[x] >= rank[y])
        {
            rank[x] += rank[y];
            pre[y] = x;
        }
        else
        {
            rank[y] += rank[y];
            pre[x] = y;
        }//不是同一个树的的节点,小树合并到大树
    }
     
    int mod(int a, int b)//取模
    {
        int ret = 1;
        while(b--)
            ret = (ret*a)%100000;
        return ret;
    }
     
    int main()
    {
        int n, m, dist;
        int x, y, a, b;
        int i, j, k;
        while(scanf("%d%d", &n, &m)!=EOF)
        {
            initSet(n);
            for(i=0; i<m; i++)
            {
                scanf("%d%d", &x, &y);
                a = findSet(x);
                b = findSet(y);
                if(a == b)//二者已在同一个连通分量,距离定是最小了
                    continue;
                dist = mod(2, i);//取模
                for(j=0; j<n; j++)//更新两个连通分量的各对经过中间对的距离
                {
                    if(a != findSet(j))
                        continue;
                    for(k=0; k<n; k++)
                    {
                        if(b != findSet(k))
                            continue;
                        d[j][k] = d[k][j] = (d[j][x]+dist+d[y][k])%100000;
                    }
                }
                unionSet(x, y);
            }
            x = findSet(0);
            for(i=1; i<n; i++)
                if(findSet(i) != x)
                    printf("-1
    ");
                else
                    printf("%d
    ", d[0][i]);
        }
    }  
    /**************************************************************
        Problem: 1100
        User: liangrx06
        Language: C
        Result: Accepted
        Time:10 ms
        Memory:952 kb
    ****************************************************************/



    编程算法爱好者。
  • 相关阅读:
    openlayers6聚合图(附源码下载)
    arcgis api 4.x for js地图加载第三方矢量切片
    leaflet读取tif像素值的两种实现方式(附源码下载)
    openlayers6热力图(附源码下载)
    cesium 3dtiles模型单体化点击高亮效果
    leaflet聚合图功能(附源码下载)
    openlayers6绘制扇形(附源码下载)
    【 Windows 10】神州网信政府版官方镜像
    Windows10 解决“装了 .NET Framework 4.5.2/4.6.1/4.7.1等等任何版本 或版本更高的更新”问题
    App.config/Web.config 中特殊字符的处理
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083932.html
Copyright © 2011-2022 走看看