codeforces 1204C Anna, Svyatoslav and Maps [最短路]
删掉一些点 但是 这些点是到下一个点(最短路方式)必须过的 输出最短序列
那莫 显然出现一个点 从上一个位置出发 能从最短路跳过去 (最短路 < dis总路程)
我们就必须让他在序列里面出现了 防止不走这个点

#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(0);cin.tie(0);
using namespace std;
typedef long long ll;
const int maxn = 1005;
const int INF = 0x3f3f3f3f;

int n, m;
int G[maxn][maxn], a[int(2e6 + 5)], ans[int(2e6 + 5)];

void floyd() {
    for(int k = 1; k <= n; k ++) 
        for(int i = 1; i <= n; i ++) 
            for(int j = 1; j <= n; j ++) 
                if(G[i][j] > G[i][k] + G[k][j]) 
                    G[i][j] = G[i][k] + G[k][j];
}

signed main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= n; j ++) {
            scanf("%1d", &m);
            if(m == 1) G[i][j] = 1;
            else G[i][j] = INF;
            if(i == j) G[i][j] = 0;
        }
    }
    floyd();
    scanf("%d", &m);
    for(int i = 1; i <= m; i ++) scanf("%d", a + i);
    int cnt = 0;
    ans[ ++ cnt] = a[1];
    int dis = 0;
    for(int i = 2; i <= m; i ++) {
        dis += G[a[i - 1]][a[i]];
        if(dis > G[ans[cnt]][a[i]]) {
            ans[++cnt] = a[i - 1];
            dis = G[ans[cnt]][a[i]];
        }
    }
    ans[++cnt] = a[m];
    cout << cnt << endl;
    for(int i = 1; i <= cnt; i ++) cout << ans[i] << " ";
    return 0;
}