Codeforces1204C. Anna, Svyatoslav and Maps (贪心 + Floyd)

Posted lubixiaosi-zhaocao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ‘\n‘
#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 ? \n :  );
    
    return 0;
View Code

 

以上是关于Codeforces1204C. Anna, Svyatoslav and Maps (贪心 + Floyd)的主要内容,如果未能解决你的问题,请参考以下文章

CF1204C Anna, Svyatoslav and Maps

CF1204C

CodeForces - 1204E Natasha, Sasha and the Prefix Sums (组合数学,卡特兰数扩展)

Codeforces Round #364 (Div. 1) 700B(树)

Codeforces 1204C

BowWow and the Timetable CodeForces - 1204A 思维