【Floyd】-寻路

UPC2020年春混合个人训练4.26日场

题目描述
明明同学被困在一个荒凉的北极岛屿,他可以用小船乘着海流用1单位时间从一个岛移动到另一个岛。他得到了一个海洋地图,有N(1<=N<=100)条单向海流航线,编号为1…N。
告诉你他的起始位置M(1<=M<=N)和地图,请编程帮助明明确定到达每个岛的最短时间是多少。
输入为一个矩阵C,第r行,第c列的值若为1,则r到c存在海流,值为0则不存在海流。
输入
明明同学被困在一个荒凉的北极岛屿,他可以用小船乘着海流用1单位时间从一个岛移动到另一个岛。他得到了一个海洋地图,有N(1<=N<=100)条单向海流航线,编号为1…N。
告诉你他的起始位置M(1<=M<=N)和地图,请编程帮助明明确定到达每个岛的最短时间是多少。
输入为一个矩阵C,第r行,第c列的值若为1,则r到c存在海流,值为0则不存在海流。
输出
第1…??行:第一行输出M,第i+1行包含时刻i能到达的岛屿(升序排列)
样例输入
4 1
0 1 0 1
0 0 1 0
0 0 0 1
0 0 0 0
样例输出
1
2 4
3
解题思路:Floyd又名弗洛伊德算法,是一种专门求两点之间最短路的算法,多的我就不说了,我也不多说了,毕竟不是一个正经的图论选手遇到这个题我也懵了,题意根本没读懂,过后问同学, 说是弗洛伊德最短路,听完懵了,过后自己有补了一波,题意是第i行第j列如果是1的话代表可以从第i个岛屿用1秒的时间到第j个岛屿,一个岛屿可能同时对应着多个岛屿,多个岛屿可能同时对应着一个岛屿,题目的要求是最短的时间到达,所以要考虑最短路了。
AC源:

/**
样例解释一波:
4 1 
0 1 0 1 
0 0 1 0 
0 0 0 1 
0 0 0 0
///一开始是在第一个岛屿,输出1,从第一个岛屿能用1秒的时间到达第二个岛屿和第四个岛屿,输出2,4,从第二个岛屿能到达第三个岛屿,
///等同于从第一个岛屿用2秒的时间能到达第三个岛屿,输出3,这里就要用到弗洛伊德算法了,从第三个岛屿能到达第四个岛屿,
///等同于从第一个岛屿用3秒的时间到达第四个岛屿,这里也就忽略了,因为在此之前已经到达了第四个岛屿
**/
#include<bits/stdc++.h>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1e6+7;
typedef pair<ll,ll> PII;
vector<int>v[110];
deque<ll>q;
int n,m;
int d[110][110];
int main(){
    cin >> n >> m;
    int x;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin >> x;
            if(i==j) d[i][j]=0;///自己到自己为0
            else if(x==1) d[i][j]=1;///说明从第i个岛屿能到达第j个岛屿,标记为1,
                                    ///也可以理解为第i个岛屿与第j个岛屿的距离为1
            else d[i][j]=1e9; ///其余情况就。。。
        }
    }
    for(int i=1;i<=n;i++) ///弗洛伊德核心思想,求出每个点之间的最短路
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=n;k++)
            {
                d[j][k]=min(d[j][k],d[j][i]+d[i][k]);
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(d[m][i]!=1e9) v[d[m][i]].push_back(i);///用到vector数组存储,
                                           ///计算从第一个岛屿开始1s,2s,3s.....到达的岛屿,
                                           ///因为一个岛屿可对应多个岛屿,所以一些岛屿是等价的
    }
    for(int i=0;;i++)///最后输出用队列也可实现,有些编译器是不能识别auto的
    {
        if(v[i].size()==0) break;
        for(auto it:v[i])
        {
            cout << it << " " ;
        }
        cout << endl;
    }
    return 0;
}

感觉图论还是很有趣的
如果不想做点事情,就不要想到达这个世界上的任何地方~

猜你喜欢

转载自blog.csdn.net/zhazhaxiaosong/article/details/105826316