The 2019 Asia Yinchuan First Round Online Programming F. Moving On

Posted ssummerzzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The 2019 Asia Yinchuan First Round Online Programming F. Moving On相关的知识,希望对你有一定的参考价值。

t题目链接:https://nanti.jisuanke.com/t/41290

思路:题目意思很容易想到floyd,但是由于危险度的限制,我们该怎么跑floyd呢。

一开始理解错题目了,以为u->v包括终点起点都不能超过给的危险度,不过看样例,好像只需要中间的城市不能超过危险度。

我们可以这么想,每个城市都有一个危险度,而floyd算法的本质是i到j经过前k个城市的转移,得到多源最短路,那么我们不妨

记录城市的编号和危险度,然后按城市的危险度排序,重新编号,危险度小的先跑floyd,然后f[k][i][j]表示经过前k个城市的最短路,

那么我们得出  f[k][i][j] = min(f[k-1][i][j],f[k-1][i][num[k]] + f[k-1][num[k][j]),从危险度小的推到危险度大的。

对于每个询问,我们只需要遍历按危险度编号的n个城市跑出的f[k][i][j],直到遍历到城市的危险度超出了危险度上限的那个f[k][u][v],

就是我们的答案了。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <cmath>
using namespace std;

typedef long long LL;
#define inf 1e9
#define rep(i, j, k) for (int i = (j); i <= (k); i++)
#define rep__(i, j, k) for (int i = (j); i < (k); i++)
#define per(i, j, k) for (int i = (j); i >= (k); i--)
#define per__(i, j, k) for (int i = (j); i > (k); i--)

const int N = 210;
int f[N][N][N];
int n,q;
int u,v,w;

struct node
    int id;
    int ATK;

    friend bool operator<(const node& a,const node& b)
        return a.ATK < b.ATK;
    
W[N];

int main()

    int T;
    scanf("%d",&T);

    rep(o,1,T)
        scanf("%d%d",&n,&q);

        rep(i,1,n)
            W[i].id = i;
            scanf("%d",&W[i].ATK);
        

        sort(W + 1,W + n + 1);

        rep(i,1,n) rep(j,1,n)
            if(i == j) f[0][i][j] = 0;
            else f[0][i][j] = inf;
        

        rep(i,1,n) rep(j,1,n)
            scanf("%d",&w);
            f[0][i][j] = w;
        

        // rep(i,1,n) cout << W[i].ATK << endl;

        // rep(i,1,n)
        //     rep(j,1,n) cout << f[0][i][j] << " ";
        //     cout << endl;
        // 

        rep(k,1,n) rep(i,1,n) rep(j,1,n)
            f[k][i][j] = min(f[k-1][i][j],f[k-1][i][W[k].id]+f[k-1][W[k].id][j]);
        

        printf("Case #%d:\n",o);

        int tmp;
        rep(i,1,q)
            scanf("%d%d%d",&u,&v,&w);
            tmp = 0;
            rep(j,1,n) if(W[j].ATK <= w) tmp = j;
            printf("%d\n",f[tmp][u][v]);
        
    

    getchar();getchar();
    return 0;

 

以上是关于The 2019 Asia Yinchuan First Round Online Programming F. Moving On的主要内容,如果未能解决你的问题,请参考以下文章

The 2019 Asia Yinchuan First Round Online Programming F. Moving On

2019 ICPC Asia Yinchuan Regional

The 2019 ICPC Asia Shanghai Regional Contest

The 2019 ICPC Asia Shanghai Regional Contest

The Preliminary Contest for ICPC Asia Shenyang 2019

The Preliminary Contest for ICPC Asia Shanghai 2019