• 最短路径 分类: 图论 2015-06-21 10:52 16人阅读 评论(0) 收藏


    最短路径
    Time Limit: 1000ms Memory limit: 65536K
    题目描述
    为了准备一年一度的校赛,大家都在忙着往赛场搬运东西,比如气球什么的。这时 YY 也没有闲着,他也加入了搬运工的行列。已知学校有 N 个路口和 M 条路,YY 并不是把东西直接搬到赛场,而是从 S 路口搬运到 T 路口。由于 YY 非常懒而且他有轻度强迫症。所以他要走的路需要尽可能的短,并且走过路径的数目要为 X 的倍数。
    输入
    输入的第一行为一个正整数T(1 ≤ T ≤ 20),代表测试数据组数。
    对于每组测试数据:
    输入的第一行为两个正整数 N 和 M(1 ≤ N ≤ 100, 1 ≤ M ≤ 10000)。
    接下来M行每行三个正整数 U、V、W(0 ≤ U, V < N, 0 ≤ W ≤ 230 ),代表有一条从U到V的长度为W的有向路径。
    最后一行为三个正整数S、T 、X(0 ≤ S, T < N, 1 ≤ X ≤ 10)。
    输出
    对于每组测试数据,输出满足条件的从 S 到 T 的最短路径。如果从 S 到 T 不可达,或者无法满足路径数是 X 的倍数,输出“No Answer!”(不包含引号)。
    注意:64-bit 整型请使用 long long 来定义,并且使用 %lld 或 cin、cout 来输入输出,请不要使用 __int64 和 %I64d。
    示例输入
    2
    2 1
    0 1 1
    0 1 2
    3 2
    0 1 1
    1 2 1
    0 2 2
    示例输出
    No Answer!
    2

    /*
    这是一道最短路SPFA算法的二维数组;
    不过我感觉我学会了点<vector>;
    有点深奥,好好研究
    */
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <climits>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int Max=110;
    const LL INF=LONG_LONG_MAX;//定义最大值
    LL dis[Max][12];//定义二维数组
    bool vis[Max];
    struct edge//定义结构体
    {
        int to;
        int w;
    };
    int n,m,s,t,x;
    vector<struct edge>map[Max];//有点类似链表,不过比链表好用多了;
    void SPFA()
    {
        queue<int>a;//定义队列
        for(int i=0; i<n; i++)//初始化
        {
            for(int k=0; k<=x; k++)
            {
                dis[i][k]=INF;
            }
        }
        memset(vis,false,sizeof(vis));
        dis[s][0]=0;
        vis[s]=true;
        a.push(s);
        while(!a.empty())
        {
            int u=a.front();
            a.pop();
            vis[u]=false;
            int tt=map[u].size();
            for(int i=0; i<tt; i++)
            {
                int to=map[u][i].to;
                for(int j=0; j<x; j++)
                {
                    if(dis[u][j]<INF&&dis[to][(j+1)%x]>dis[u][j]+map[u][i].w)//松弛操作
                    {
                        dis[to][(j+1)%x]=dis[u][j]+map[u][i].w;
                        if(!vis[to])
                        {
                            a.push(to);
                            vis[to]=true;
                        }
                    }
                }
            }
        }
    }
    int main()
    {
        int T,u,v,w;
        struct edge tmp;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d %d",&n,&m);
            for(int i=0; i<n; i++)//清空数组
            {
                map[i].clear();
            }
            for(int i=1; i<=m; i++)
            {
                scanf("%d %d %d",&u,&v,&w);
                tmp.to=v;
                tmp.w=w;
                map[u].push_back(tmp);
            }
            scanf("%d %d %d",&s,&t,&x);
            SPFA();
            if(dis[t][0]>=INF)
            {
                printf("No Answer!
    ");
            }
            else
            {
                printf("%lld
    ",dis[t][0]);
            }
        }
        return 0;
    }
    

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    关于如何学习C语言
    2020软件工程作业04
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    3.语法树,短语,直接短语,句柄
    2.文法和语言
    Linux——如何将Red Hat Enterprise Linux 6的语言改为中文?
    编译原理概述
    编译原理概述-第一次作业
  • 原文地址:https://www.cnblogs.com/juechen/p/4722003.html
Copyright © 2020-2023  润新知