zoukankan      html  css  js  c++  java
  • Codeforces1204C. Anna, Svyatoslav and Maps (贪心 + Floyd)

    题目链接:传送门


    题目大意:

    给出n<=100的有向图,和路径p,求p的最短子序列v,使得依次经过v中所有点的路径为p。


    思路:

    题意其实就是让我们求路径上的一些关键点v,对于所有的关键点:vi到vi+1的最短路的长度,等于vi到vi+1这两个点在序列p中的下标的差,且vi到vi+2的最短路的长度,小于vi到vi+2在序列p中的下标的差

    如果用dis[u][v] 表示:在题目给出的有向图中,从u出发到v的最短路径的长度。则:

    1、p1和pm都是关键点。

    2、假设u是之前的最后一个关键点,如果dis[u][pi+1] != dis[u][pi] + 1,则pi就是下一个关键点。

    那么用Floyd预处理任意两点间的最短路,就可以O(m)地跑一遍数组p,得到所有的关键点,就是答案了。


    代码:O(n3+m)

    #include <bits/stdc++.h>
    #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    #define N 105
    #define M 1000005
    #define INF 0x3f3f3f3f
    #define mk(x) (1<<x) // be conscious if mask x exceeds int
    #define sz(x) ((int)x.size())
    #define lson(x) (x<<1)
    #define rson(x) (x<<1|1)
    #define mp(a,b) make_pair(a, b)
    #define endl '
    '
    #define lowbit(x) (x&-x)
    
    using namespace std;
    typedef long long ll;
    typedef double db;
    
    /** fast read **/
    template <typename T>
    inline void read(T &x) {
        x = 0; T fg = 1; char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') fg = -1;
            ch = getchar();
        }
        while (isdigit(ch)) x = x*10+ch-'0', ch = getchar();
        x = fg * x;
    }
    template <typename T, typename... Args>
    inline void read(T &x, Args &... args) { read(x), read(args...); }
    
    int n, m;
    int a[N][N];
    bool cant[N][N];
    int p[M];
    
    void Folyd() {
        memset(cant, false, sizeof cant);
        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) if (i != k) {
                for (int j = 1; j <= n; j++) if (j != i && j != k) {
                    if (a[i][j] > a[i][k] + a[k][j])
                        a[i][j] = a[i][k] + a[k][j];
                    else if (a[i][j] == a[i][k] + a[k][j]) {
                        cant[i][j] = true;
                    }
                }
            }
        }
    }
    
    vector <int> ans;
    int main()
    {
        read(n);
        for (int i = 1; i <= n; i++) {
            string s; cin >> s;
            for (int j = 1; j <= n; j++) {
                if (j == i)
                    a[i][j] = 0;
                else if (s[j-1] == '1')
                    a[i][j] = 1;
                else
                    a[i][j] = 1e5;
            }
        }
        read(m);
        for (int i = 1; i <= m; i++) {
            read(p[i]);
        }
        Folyd();
        int u = p[1];
        ans.push_back(u);
        for (int i = 2; i <= m; i++) {
            if (a[u][p[i]] > a[u][p[i-1]])
                continue;
            u = p[i-1];
            ans.push_back(u);
        }
        ans.push_back(p[m]);
        cout << ans.size() << endl;
        for (int i = 0; i < sz(ans); i++) {
            printf("%d%c", ans[i], i == sz(ans)-1 ? '
    ' : ' ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Java实现第八届蓝桥杯9算数式
    Java实现第八届蓝桥杯9算数式
    java实现第七届蓝桥杯寒假作业
    java实现第七届蓝桥杯寒假作业
    java实现第六届蓝桥杯隔行变色
    java实现第六届蓝桥杯无穷分数
    mysql-5.7.19-winx64服务无法启动解决方案
    MySQL集群搭建详解
    Windows下多个Mysql实例配置主从
    在一台机子上,安装,运行两mysql数据库实例
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/11634811.html
Copyright © 2011-2022 走看看